├── .eslintignore
├── .eslintrc
├── .github
└── FUNDING.yml
├── .gitignore
├── .npmignore
├── .postcssrc
├── README.md
├── babel.config.js
├── build
├── rollup.config.base.js
├── rollup.config.browser.js
├── rollup.config.es.js
└── rollup.config.umd.js
├── dist
└── .gitkeep
├── docs-src
├── .babelrc
├── App.vue
├── assets
│ └── logo.png
├── components
│ └── MyTab.vue
├── demo-routes.js
├── helpers.js
├── main.js
├── router.js
├── store.js
└── views
│ ├── About.vue
│ ├── Home.vue
│ └── demos
│ ├── Button.vue
│ ├── ButtonGroup.vue
│ ├── Colors.vue
│ ├── Disable.vue
│ ├── Dropdown.vue
│ ├── Icon.vue
│ ├── Input.vue
│ ├── Loading.vue
│ ├── Modal.vue
│ ├── Select.vue
│ ├── Switch.vue
│ ├── Tabs.vue
│ ├── Tooltip.vue
│ └── TypeAhead.vue
├── docs
├── .nojekyll
├── css
│ └── app.7d07430f.css
├── index.html
├── js
│ ├── app.94ab3425.js
│ ├── app.94ab3425.js.map
│ ├── chunk-vendors.28127d79.js
│ └── chunk-vendors.28127d79.js.map
└── logo.png
├── package.json
├── public
├── .nojekyll
├── index.html
└── logo.png
├── src
├── components
│ ├── VueButton.vue
│ ├── VueDisable.vue
│ ├── VueDropdown.vue
│ ├── VueDropdownButton.vue
│ ├── VueFormField.vue
│ ├── VueGroup.vue
│ ├── VueGroupButton.vue
│ ├── VueIcon.js
│ ├── VueInput.vue
│ ├── VueLoadingBar.js
│ ├── VueLoadingIndicator.js
│ ├── VueModal.vue
│ ├── VueSelect.vue
│ ├── VueSelectButton.vue
│ ├── VueSwitch.vue
│ ├── VueTab.vue
│ ├── VueTabs.vue
│ └── VueTypeAhead.vue
├── icons.js
├── index.js
├── mixins
│ ├── CoupledChild.js
│ ├── CoupledParent.js
│ ├── DisableScroll.js
│ ├── DisabledChild.js
│ └── DisabledParent.js
└── style
│ ├── animation.styl
│ ├── base.styl
│ ├── colors.styl
│ ├── imports.styl
│ ├── md-colors.styl
│ ├── mixins.styl
│ ├── tooltip.styl
│ └── vars.styl
├── vue.config.js
└── yarn.lock
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | dist/
3 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "extends": [
4 | "plugin:vue/essential",
5 | "@vue/standard"
6 | ],
7 | "rules": {
8 | "comma-dangle": ["error", "always-multiline"]
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: Akryum
2 | open_collective: vuejs
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 |
4 | # local env files
5 | .env.local
6 | .env.*.local
7 |
8 | # Log files
9 | npm-debug.log*
10 | yarn-debug.log*
11 | yarn-error.log*
12 |
13 | # Editor directories and files
14 | .idea
15 | .vscode
16 | *.suo
17 | *.ntvs*
18 | *.njsproj
19 | *.sln
20 |
21 | /dist
22 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | docs/
2 | docs-src/
3 | public/
4 | .babelrc
5 | .eslintrc
6 | .postcssrc
7 |
--------------------------------------------------------------------------------
/.postcssrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": {
3 | "autoprefixer": {},
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Vue UI Framework
2 |
3 | [](https://www.npmjs.com/package/@vue/ui)
4 | [](https://vuejs.org/)
5 |
6 | This is a collection of components and styles meant to be used across all official Vue.js apps.
7 |
8 | ## Installation
9 |
10 | Install the `@vue/ui` package:
11 |
12 | ```
13 | npm i -S @vue/ui
14 | ```
15 |
16 | Install the Vue plugin:
17 |
18 | ```js
19 | import Vue from 'vue'
20 | import VueUi from '@vue/ui'
21 |
22 | Vue.use(VueUi)
23 | ```
24 |
25 | Import the CSS:
26 |
27 | ```js
28 | import '@vue/ui/dist/vue-ui.css'
29 | ```
30 |
31 | **Documentation is Work In Progress**
32 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'presets': [
3 | '@vue/babel-preset-jsx',
4 | [
5 | '@babel/env', {
6 | 'modules': false,
7 | },
8 | ],
9 | ],
10 | }
11 |
--------------------------------------------------------------------------------
/build/rollup.config.base.js:
--------------------------------------------------------------------------------
1 | import { babel } from '@rollup/plugin-babel'
2 | import resolve from '@rollup/plugin-node-resolve'
3 | import vue from 'rollup-plugin-vue'
4 | import cjs from '@rollup/plugin-commonjs'
5 | import replace from '@rollup/plugin-replace'
6 | import requireContext from 'rollup-plugin-require-context'
7 | import { string } from 'rollup-plugin-string'
8 | import fs from 'fs-extra'
9 | import CleanCSS from 'clean-css'
10 | import autoprefixer from 'autoprefixer'
11 | import css from 'rollup-plugin-css-only'
12 |
13 | const config = require('../package.json')
14 |
15 | export default {
16 | input: 'src/index.js',
17 | plugins: [
18 | resolve({
19 | mainFields: ['module', 'jsnext', 'main', 'browser'],
20 | }),
21 | string({
22 | include: '**/*.svg',
23 | }),
24 | vue({
25 | css: false,
26 | style: {
27 | postcssPlugins: [autoprefixer],
28 | },
29 | }),
30 | babel({
31 | exclude: 'node_modules/**',
32 | presets: [
33 | '@vue/babel-preset-jsx',
34 | [
35 | '@babel/env', {
36 | 'modules': false,
37 | },
38 | ],
39 | ],
40 | }),
41 | css({
42 | output: styles => {
43 | fs.ensureDirSync('dist')
44 | fs.writeFileSync('dist/vue-ui.css', new CleanCSS().minify(styles).styles)
45 | },
46 | }),
47 | cjs({
48 | exclude: 'src/**',
49 | }),
50 | requireContext(),
51 | replace({
52 | VERSION: JSON.stringify(config.version),
53 | }),
54 | ],
55 | watch: {
56 | include: 'src/**',
57 | },
58 | external: [
59 | 'vue',
60 | ],
61 | }
62 |
--------------------------------------------------------------------------------
/build/rollup.config.browser.js:
--------------------------------------------------------------------------------
1 | import base from './rollup.config.base'
2 | import { terser } from 'rollup-plugin-terser'
3 |
4 | const config = Object.assign({}, base, {
5 | output: {
6 | exports: 'named',
7 | name: 'VueUi',
8 | file: 'dist/vue-ui.min.js',
9 | format: 'iife',
10 | sourcemap: true,
11 | globals: {
12 | vue: 'Vue',
13 | },
14 | },
15 | })
16 |
17 | config.plugins.push(terser())
18 |
19 | export default config
20 |
--------------------------------------------------------------------------------
/build/rollup.config.es.js:
--------------------------------------------------------------------------------
1 | import base from './rollup.config.base'
2 |
3 | const config = Object.assign({}, base, {
4 | output: {
5 | name: 'vue-ui',
6 | file: 'dist/vue-ui.esm.js',
7 | format: 'es',
8 | sourcemap: true,
9 | },
10 | external: [
11 | ...base.external,
12 | 'focus-visible',
13 | 'v-tooltip',
14 | 'vue-resize',
15 | ],
16 | })
17 |
18 | export default config
19 |
--------------------------------------------------------------------------------
/build/rollup.config.umd.js:
--------------------------------------------------------------------------------
1 | import base from './rollup.config.base'
2 |
3 | const config = Object.assign({}, base, {
4 | output: {
5 | exports: 'named',
6 | name: 'vue-ui',
7 | file: 'dist/vue-ui.umd.js',
8 | format: 'umd',
9 | sourcemap: true,
10 | },
11 | })
12 |
13 | export default config
14 |
--------------------------------------------------------------------------------
/dist/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vuejs/ui/63f67359862e9ef8d5e679172e4aa01f922271be/dist/.gitkeep
--------------------------------------------------------------------------------
/docs-src/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "@vue/app"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/docs-src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Home |
5 |
About
6 |
7 |
8 | Default
9 | Dark
10 | High contrast
11 |
12 |
13 |
14 |
15 |
16 |
17 |
30 |
31 |
81 |
--------------------------------------------------------------------------------
/docs-src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vuejs/ui/63f67359862e9ef8d5e679172e4aa01f922271be/docs-src/assets/logo.png
--------------------------------------------------------------------------------
/docs-src/components/MyTab.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
15 |
--------------------------------------------------------------------------------
/docs-src/demo-routes.js:
--------------------------------------------------------------------------------
1 | const nameReg = /([a-z0-9]+)\./i
2 | const demos = require.context('./views/demos', true, /[a-z0-9]+\.(jsx?|vue)$/i)
3 |
4 | export default demos.keys().map(key => {
5 | const name = key.match(nameReg)[1]
6 | return {
7 | path: `${name.toLowerCase()}`,
8 | name: `demo-${name.toLowerCase()}`,
9 | component: demos(key).default,
10 | meta: {
11 | label: name,
12 | },
13 | }
14 | })
15 |
--------------------------------------------------------------------------------
/docs-src/helpers.js:
--------------------------------------------------------------------------------
1 | export function versionCompare (v1, v2, options) {
2 | const lexicographical = options && options.lexicographical
3 | const zeroExtend = options && options.zeroExtend
4 | let v1parts = v1.split('.')
5 | let v2parts = v2.split('.')
6 |
7 | function isValidPart (x) {
8 | return (lexicographical ? /^\d+[A-Za-z]*$/ : /^\d+$/).test(x)
9 | }
10 |
11 | if (!v1parts.every(isValidPart) || !v2parts.every(isValidPart)) {
12 | return NaN
13 | }
14 |
15 | if (zeroExtend) {
16 | while (v1parts.length < v2parts.length) v1parts.push('0')
17 | while (v2parts.length < v1parts.length) v2parts.push('0')
18 | }
19 |
20 | if (!lexicographical) {
21 | v1parts = v1parts.map(Number)
22 | v2parts = v2parts.map(Number)
23 | }
24 |
25 | for (let i = 0; i < v1parts.length; ++i) {
26 | if (v2parts.length === i) {
27 | return 1
28 | }
29 |
30 | if (v1parts[i] === v2parts[i]) {
31 |
32 | } else if (v1parts[i] > v2parts[i]) {
33 | return 1
34 | } else {
35 | return -1
36 | }
37 | }
38 |
39 | if (v1parts.length !== v2parts.length) {
40 | return -1
41 | }
42 |
43 | return 0
44 | }
45 |
--------------------------------------------------------------------------------
/docs-src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import router from './router'
4 | import store from './store'
5 | import VueUiFramework from '../'
6 | import '../dist/vue-ui.css'
7 |
8 | Vue.use(VueUiFramework, /* {
9 | vtooltip: {
10 | themes: {
11 | tooltip: {
12 | delay: 2000,
13 | },
14 | },
15 | },
16 | } */)
17 |
18 | Vue.config.productionTip = false
19 |
20 | Vue.prototype.log = (...args) => {
21 | console.log(...args)
22 | }
23 |
24 | new Vue({
25 | router,
26 | store,
27 | ...App,
28 | }).$mount('#app')
29 |
--------------------------------------------------------------------------------
/docs-src/router.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import Home from './views/Home.vue'
4 | import About from './views/About.vue'
5 | import demos from './demo-routes'
6 |
7 | Vue.use(Router)
8 |
9 | export default new Router({
10 | routes: [
11 | {
12 | path: '/',
13 | name: 'home',
14 | component: Home,
15 | },
16 | {
17 | path: '/about',
18 | name: 'about',
19 | component: About,
20 | },
21 | {
22 | path: '/demo',
23 | component: Home,
24 | children: demos,
25 | },
26 | ],
27 | })
28 |
--------------------------------------------------------------------------------
/docs-src/store.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | Vue.use(Vuex)
5 |
6 | export default new Vuex.Store({
7 | state: {
8 | theme: 'default',
9 | },
10 | mutations: {
11 | 'SWITCH_THEME': (state, value) => {
12 | state.theme = value
13 | localStorage.setItem('vue-ui:theme', value)
14 | const el = document.getElementsByTagName('html')[0]
15 | if (value !== 'default') {
16 | el.classList.add('vue-ui-dark-mode')
17 | } else {
18 | el.classList.remove('vue-ui-dark-mode')
19 | }
20 | if (value !== 'high-contrast') {
21 | el.classList.remove('vue-ui-high-contrast')
22 | } else {
23 | el.classList.add('vue-ui-high-contrast')
24 | }
25 | },
26 | },
27 | actions: {
28 |
29 | },
30 | })
31 |
--------------------------------------------------------------------------------
/docs-src/views/About.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
This is an about page
4 |
5 |
6 |
--------------------------------------------------------------------------------
/docs-src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
11 | {{ demo.meta.label }}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
33 |
34 |
69 |
--------------------------------------------------------------------------------
/docs-src/views/demos/ButtonGroup.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
VueGroup + VueGroupButton
5 |
6 |
7 | Choice: {{ choice }}
8 | Reset
9 |
10 |
11 | Show orange fruit
12 |
13 |
14 |
15 |
16 |
17 | {{ fruit }}
18 |
19 |
20 | {{ fruit }}
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
Vertical
31 |
32 |
33 | {{ fruit }}
34 |
35 |
36 | {{ fruit }}
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | {{ fruit }}
46 |
47 |
48 | {{ fruit }}
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | {{ fruit }}
58 |
59 |
60 | {{ fruit }}
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
Styles
71 |
72 |
73 | {{ fruit }}
74 |
75 |
76 | {{ fruit }}
77 |
78 |
79 | {{ fruit }}
80 |
81 |
82 | {{ fruit }}
83 |
84 |
85 | {{ fruit }}
86 |
87 |
88 | {{ fruit }}
89 |
90 |
91 | {{ fruit }}
92 |
93 |
94 |
95 |
With indicator
96 |
97 |
98 | {{ fruit }}
99 |
100 |
101 | {{ fruit }}
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | {{ fruit }}
112 |
113 |
114 | {{ fruit }}
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 | {{ fruit }}
126 |
127 |
128 | {{ fruit }}
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 | {{ fruit }}
139 |
140 |
141 | {{ fruit }}
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 | {{ fruit }}
153 |
154 |
155 | {{ fruit }}
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 | {{ fruit }}
166 |
167 |
168 | {{ fruit }}
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 | {{ fruit }}
180 |
181 |
182 | {{ fruit }}
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 | {{ fruit }}
195 |
196 |
197 | {{ fruit }}
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 | {{ fruit }}
209 |
210 |
211 | {{ fruit }}
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 | {{ fruit }}
224 |
225 |
226 | {{ fruit }}
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 | {{ fruit }}
238 |
239 |
240 | {{ fruit }}
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 | {{ fruit }}
253 |
254 |
255 | {{ fruit }}
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
With indicator - Vertical
266 |
267 |
268 | {{ fruit }}
269 |
270 |
271 | {{ fruit }}
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 | {{ fruit }}
284 |
285 |
286 | {{ fruit }}
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 | {{ fruit }}
298 |
299 |
300 | {{ fruit }}
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 | {{ fruit }}
313 |
314 |
315 | {{ fruit }}
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 | {{ fruit }}
327 |
328 |
329 | {{ fruit }}
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 | {{ fruit }}
340 |
341 |
342 | {{ fruit }}
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 | {{ fruit }}
354 |
355 |
356 | {{ fruit }}
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 | {{ fruit }}
369 |
370 |
371 | {{ fruit }}
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 | {{ fruit }}
383 |
384 |
385 | {{ fruit }}
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 | {{ fruit }}
398 |
399 |
400 | {{ fruit }}
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 | {{ fruit }}
412 |
413 |
414 | {{ fruit }}
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 | {{ fruit }}
427 |
428 |
429 | {{ fruit }}
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
465 |
466 |
475 |
--------------------------------------------------------------------------------
/docs-src/views/demos/Colors.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Colors
5 |
6 |
11 |
17 |
18 |
{{ type }}-{{ i }}00
19 |
20 |
21 |
22 |
23 |
24 |
25 |
52 |
--------------------------------------------------------------------------------
/docs-src/views/demos/Disable.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
VueDisable
5 |
6 |
7 | Disable root
8 |
9 |
10 | Disable level 1 A
11 |
12 |
13 | Disable level 1 B (with stop propagation)
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | vuejs.org
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | Edit
37 | Delete
38 | Keep open
39 |
40 |
41 |
42 |
43 |
44 |
45 | vuejs.org
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | Edit
61 | Delete
62 | Keep open
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | vuejs.org
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | Edit
87 | Delete
88 | Keep open
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
112 |
113 |
125 |
--------------------------------------------------------------------------------
/docs-src/views/demos/Dropdown.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
VueDropdown
5 |
6 |
7 |
8 | Edit
9 | Delete
10 | Keep open
11 |
12 |
13 |
14 | Edit
15 | Delete
16 | Keep open
17 |
18 |
19 |
20 | Edit
21 | Delete
22 | Keep open
23 |
24 |
25 |
26 |
31 |
32 | Edit
33 | Delete
34 | Keep open
35 |
36 |
37 |
38 | Bookmark
39 | Build
40 | Backup and Restore Settings
41 |
42 |
43 |
44 |
45 | Result 1
46 | Result 2
47 | Result 3
48 |
49 |
50 |
51 |
52 | Edit
53 | Delete
54 | Keep open
55 | Hello
56 |
57 |
58 |
59 |
60 |
61 | Edit
62 | Delete
63 | Keep open
64 | Hello
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
82 |
--------------------------------------------------------------------------------
/docs-src/views/demos/Icon.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
VueIcon
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | 500
18 |
19 | on GitHub
20 |
21 |
22 |
23 | 500
24 |
25 | on GitHub
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/docs-src/views/demos/Input.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
VueInput
5 |
6 |
Message: {{ string }}
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Reset
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | Reset
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | With suggestion:
40 |
41 |
42 |
Textarea:
43 |
44 |
45 |
46 |
47 |
48 |
Big:
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
VueFormField
59 |
60 |
61 |
65 |
66 |
67 |
68 |
72 |
73 | The message is invalid doc
74 |
75 |
76 |
81 |
82 |
83 |
84 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
118 |
--------------------------------------------------------------------------------
/docs-src/views/demos/Loading.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
VueLoadingIndicator
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | Inline:
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | Toggle loading overlay
30 |
34 | Close
35 |
36 |
37 |
38 |
39 |
40 |
VueLoadingBar
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
69 |
70 |
--------------------------------------------------------------------------------
/docs-src/views/demos/Modal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
VueModal
5 |
6 |
7 | Open small modal
8 |
9 |
10 | Locked
11 |
12 |
13 |
20 |
21 | Et accusamus et exercitationem in neque consequatur libero illo. Excepturi voluptas rerum nostrum quidem voluptatem. Quidem harum consectetur voluptate ut. Quia quae accusantium debitis. Quos ad deserunt dolorem. Tenetur qui aspernatur velit.
22 |
23 |
24 |
25 | Close
26 |
27 |
28 |
29 |
30 |
31 |
32 |
42 |
--------------------------------------------------------------------------------
/docs-src/views/demos/Select.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
VueSelect
5 |
6 |
7 | Reset
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
62 |
63 |
69 |
--------------------------------------------------------------------------------
/docs-src/views/demos/Switch.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
VueSwitch
5 |
6 |
7 |
8 | Enable setting
9 |
10 |
11 | Enable setting
12 |
13 |
14 | Disabled setting
15 |
16 |
17 | Disabled setting
18 |
19 |
20 | Disabled setting
21 |
22 |
23 | Disabled setting
24 |
25 |
26 | Disabled setting
27 |
28 |
29 | Disabled setting
30 |
31 |
32 |
33 |
With icon:
34 |
35 |
36 |
37 | Enable setting
38 |
39 |
40 | Enable setting
41 |
42 |
43 | Disabled setting
44 |
45 |
46 | Disabled setting
47 |
48 |
49 | Disabled setting
50 |
51 |
52 | Disabled setting
53 |
54 |
55 | Disabled setting
56 |
57 |
58 | Disabled setting
59 |
60 |
61 |
62 |
63 |
64 |
65 |
74 |
--------------------------------------------------------------------------------
/docs-src/views/demos/Tabs.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
VueTabs
5 |
6 |
7 |
8 |
12 | Content 1
13 |
14 |
18 | Content 2
19 |
20 |
24 | Content 3
25 |
26 |
27 |
28 |
29 |
30 |
31 |
36 | Content 1
37 |
38 |
43 | Content 2
44 |
45 |
50 | Content 3
51 |
52 |
53 |
54 |
55 |
56 |
57 |
61 | Content 1
62 |
63 |
67 | Content 2
68 |
69 |
73 | Content 3
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
96 |
97 |
101 |
--------------------------------------------------------------------------------
/docs-src/views/demos/Tooltip.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
VTooltip
5 |
6 | Hover me!
7 | Disabled button
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/docs-src/views/demos/TypeAhead.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
VueTypeAhead
5 |
6 |
7 |
13 |
21 |
30 |
31 |
32 |
33 |
34 |
35 |
80 |
--------------------------------------------------------------------------------
/docs/.nojekyll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vuejs/ui/63f67359862e9ef8d5e679172e4aa01f922271be/docs/.nojekyll
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 | Vue UI Framework
--------------------------------------------------------------------------------
/docs/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vuejs/ui/63f67359862e9ef8d5e679172e4aa01f922271be/docs/logo.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@vue/ui",
3 | "description": "UI components used in the vuejs organization apps",
4 | "version": "0.12.5",
5 | "author": {
6 | "name": "Guillaume Chau",
7 | "email": "guillaume.b.chau@gmail.com"
8 | },
9 | "keywords": [
10 | "vue",
11 | "vuejs"
12 | ],
13 | "license": "MIT",
14 | "main": "dist/vue-ui.umd.js",
15 | "module": "dist/vue-ui.esm.js",
16 | "unpkg": "dist/vue-ui.min.js",
17 | "scripts": {
18 | "demo:serve": "vue-cli-service serve",
19 | "demo:build": "vue-cli-service build",
20 | "demo:lint": "vue-cli-service lint",
21 | "lint": "eslint --ext .js,.vue src/",
22 | "dev": "nodemon --exec 'npm run build:es' --watch src -e js,vue,styl",
23 | "build": "npm run build:browser && npm run build:es && npm run build:umd",
24 | "build:browser": "rollup --config build/rollup.config.browser.js",
25 | "build:es": "rollup --config build/rollup.config.es.js",
26 | "build:umd": "rollup --config build/rollup.config.umd.js",
27 | "prepublishOnly": "yarn run lint && yarn run build"
28 | },
29 | "repository": {
30 | "type": "git",
31 | "url": "git+https://github.com/vuejs/ui.git"
32 | },
33 | "bugs": {
34 | "url": "https://github.com/vuejs/ui/issues"
35 | },
36 | "homepage": "https://github.com/vuejs/ui#readme",
37 | "publishConfig": {
38 | "access": "public"
39 | },
40 | "dependencies": {
41 | "focus-visible": "^5.2.0",
42 | "v-tooltip": "^3.0.0-alpha.20",
43 | "vue-resize": "^1.0.0"
44 | },
45 | "devDependencies": {
46 | "@akryum/md-icons-svg": "^1.0.1",
47 | "@babel/core": "^7.12.10",
48 | "@babel/plugin-transform-runtime": "^7.4.0",
49 | "@babel/preset-env": "^7.4.2",
50 | "@rollup/plugin-babel": "^5.2.2",
51 | "@rollup/plugin-commonjs": "^11.0.2",
52 | "@rollup/plugin-node-resolve": "^7.1.1",
53 | "@rollup/plugin-replace": "^2.3.1",
54 | "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1",
55 | "@vue/babel-preset-jsx": "^1.2.4",
56 | "@vue/cli-plugin-babel": "^3.5.1",
57 | "@vue/cli-plugin-eslint": "^3.5.1",
58 | "@vue/cli-service": "^3.5.1",
59 | "@vue/eslint-config-standard": "^4.0.0",
60 | "babel-eslint": "^10.0.1",
61 | "clean-css": "^4.1.8",
62 | "core-js": "^2.0.0",
63 | "cross-env": "^5.1.3",
64 | "fs-extra": "^9.1.0",
65 | "nodemon": "^1.17.5",
66 | "raw-loader": "^2.0.0",
67 | "rollup": "^2.38.2",
68 | "rollup-plugin-css-only": "^3.1.0",
69 | "rollup-plugin-require-context": "^0.0.2",
70 | "rollup-plugin-string": "^3.0.0",
71 | "rollup-plugin-terser": "^7.0.2",
72 | "rollup-plugin-vue": "^4",
73 | "stylus": "^0.54.5",
74 | "stylus-loader": "^3.0.1",
75 | "vue": "^2.6.10",
76 | "vue-router": "^3.0.1",
77 | "vue-template-compiler": "^2.6.10",
78 | "vuex": "^3.0.1"
79 | },
80 | "peerDependencies": {
81 | "vue": "^2.5.13"
82 | },
83 | "resolutions": {
84 | "upath": "1.1.0"
85 | },
86 | "browserslist": [
87 | "> 10%",
88 | "last 2 versions"
89 | ]
90 | }
91 |
--------------------------------------------------------------------------------
/public/.nojekyll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vuejs/ui/63f67359862e9ef8d5e679172e4aa01f922271be/public/.nojekyll
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Vue UI Framework
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vuejs/ui/63f67359862e9ef8d5e679172e4aa01f922271be/public/logo.png
--------------------------------------------------------------------------------
/src/components/VueButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
21 |
24 |
25 |
28 |
32 |
37 |
38 |
39 |
40 | {{ label }}
41 |
42 |
43 |
44 |
47 |
48 |
53 |
54 |
55 |
56 |
57 |
134 |
135 |
333 |
--------------------------------------------------------------------------------
/src/components/VueDisable.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
44 |
--------------------------------------------------------------------------------
/src/components/VueDropdown.vue:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 | {{ label }}
21 |
22 |
23 |
24 |
25 |
35 |
36 |
37 |
38 |
39 |
43 |
44 |
45 |
46 |
159 |
160 |
198 |
--------------------------------------------------------------------------------
/src/components/VueDropdownButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 |
26 |
27 |
38 |
--------------------------------------------------------------------------------
/src/components/VueFormField.vue:
--------------------------------------------------------------------------------
1 |
2 |
34 |
35 |
36 |
102 |
103 |
142 |
--------------------------------------------------------------------------------
/src/components/VueGroup.vue:
--------------------------------------------------------------------------------
1 |
2 |
30 |
31 |
32 |
121 |
122 |
220 |
--------------------------------------------------------------------------------
/src/components/VueGroupButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
63 |
64 |
165 |
--------------------------------------------------------------------------------
/src/components/VueIcon.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: 'VueIcon',
3 |
4 | functional: true,
5 |
6 | props: {
7 | icon: {
8 | type: String,
9 | required: true,
10 | },
11 | },
12 |
13 | render (h, { props, data }) {
14 | return
18 |
19 |
20 |
21 |
22 | },
23 | }
24 |
--------------------------------------------------------------------------------
/src/components/VueInput.vue:
--------------------------------------------------------------------------------
1 |
2 |
71 |
72 |
73 |
224 |
225 |
433 |
--------------------------------------------------------------------------------
/src/components/VueLoadingBar.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: 'VueLoadingBar',
3 |
4 | functional: true,
5 |
6 | props: {
7 | value: {
8 | type: Number,
9 | default: 0,
10 | },
11 |
12 | unknown: {
13 | type: Boolean,
14 | default: false,
15 | },
16 | },
17 |
18 | render (h, { props, data }) {
19 | data.class = [
20 | data.class,
21 | {
22 | unknown: props.unknown,
23 | },
24 | ]
25 | return
34 | },
35 | }
36 |
--------------------------------------------------------------------------------
/src/components/VueLoadingIndicator.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: 'VueLoadingIndicator',
3 |
4 | functional: true,
5 |
6 | render (h, { data, children }) {
7 | return
11 | },
12 | }
13 |
--------------------------------------------------------------------------------
/src/components/VueModal.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
20 |
24 |
25 |
29 |
38 |
39 |
40 |
41 |
44 |
45 |
51 |
52 |
53 |
54 |
55 |
56 |
93 |
94 |
213 |
--------------------------------------------------------------------------------
/src/components/VueSelect.vue:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
126 |
127 |
139 |
--------------------------------------------------------------------------------
/src/components/VueSelectButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
14 |
15 |
49 |
50 |
56 |
--------------------------------------------------------------------------------
/src/components/VueSwitch.vue:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
77 |
78 |
203 |
--------------------------------------------------------------------------------
/src/components/VueTab.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
20 |
21 |
22 |
23 |
95 |
96 |
102 |
--------------------------------------------------------------------------------
/src/components/VueTabs.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
17 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
171 |
172 |
216 |
--------------------------------------------------------------------------------
/src/components/VueTypeAhead.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | open = val"
6 | trigger="manual"
7 | v-model="valueModel"
8 | :auto-hide="!focused"
9 | no-popover-focus
10 | @popover-mousedown="onPopoverContentMousedown"
11 | @popover-mouseup="onPopoverContentMouseup"
12 | >
13 |
23 |
24 |
25 |
31 | {{ suggestion.label || suggestion.value }}
32 |
33 |
34 |
35 |
36 |
37 |
38 |
235 |
236 |
246 |
--------------------------------------------------------------------------------
/src/icons.js:
--------------------------------------------------------------------------------
1 | const icons = require.context('../node_modules/@akryum/md-icons-svg/svg/', true, /materialicons\/24px\.svg$/)
2 |
3 | export default {
4 | install (Vue) {
5 | const sprites = ['']
6 | let spriteIndex = 0
7 | // Load all the SVG symbols
8 | icons.keys().forEach((key, index) => {
9 | let result = icons(key)
10 | const [, iconName] = /(\w+)\/materialicons/.exec(key)
11 | const [, content] = /(.*)<\/svg>/.exec(result)
12 | result = `${content} `
13 | sprites[spriteIndex] += result
14 | if ((index + 1) % 40 === 0) {
15 | sprites.push('')
16 | spriteIndex++
17 | }
18 | })
19 | for (const html of sprites) {
20 | const iconsWrapper = document.createElement('div')
21 | iconsWrapper.style.display = 'none'
22 | iconsWrapper.innerHTML = html
23 | document.body.insertBefore(iconsWrapper, document.body.firstChild)
24 | }
25 | },
26 | }
27 |
28 | export function generateHtmlIcon (icon) {
29 | return `
`
30 | }
31 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import VueIcons from './icons'
2 | import VTooltip from 'v-tooltip'
3 | import VueResize from 'vue-resize'
4 | import 'focus-visible'
5 |
6 | import 'vue-resize/dist/vue-resize.css'
7 | import 'v-tooltip/dist/v-tooltip.css'
8 |
9 | import VueButton from './components/VueButton.vue'
10 | import VueDisable from './components/VueDisable.vue'
11 | import VueDropdown from './components/VueDropdown.vue'
12 | import VueDropdownButton from './components/VueDropdownButton.vue'
13 | import VueFormField from './components/VueFormField.vue'
14 | import VueGroup from './components/VueGroup.vue'
15 | import VueGroupButton from './components/VueGroupButton.vue'
16 | import VueIcon from './components/VueIcon'
17 | import VueInput from './components/VueInput.vue'
18 | import VueLoadingBar from './components/VueLoadingBar'
19 | import VueLoadingIndicator from './components/VueLoadingIndicator'
20 | import VueModal from './components/VueModal.vue'
21 | import VueSelect from './components/VueSelect.vue'
22 | import VueSelectButton from './components/VueSelectButton.vue'
23 | import VueSwitch from './components/VueSwitch.vue'
24 | import VueTab from './components/VueTab.vue'
25 | import VueTabs from './components/VueTabs.vue'
26 | import VueTypeAhead from './components/VueTypeAhead.vue'
27 |
28 | // Exported mixins
29 | export { default as CoupledChild } from './mixins/CoupledChild'
30 | export { default as CoupledParent } from './mixins/CoupledParent'
31 | export { default as DisabledChild } from './mixins/DisabledChild'
32 | export { default as DisableScroll } from './mixins/DisableScroll'
33 |
34 | // Exported utils
35 | export { generateHtmlIcon } from './icons'
36 |
37 | export function install (Vue, options = {}) {
38 | Vue.use(VueIcons)
39 |
40 | Vue.use(VTooltip, mergeOptions({
41 | bondary: document.body,
42 | themes: {
43 | tooltip: {
44 | delay: {
45 | show: 1000,
46 | hide: 800,
47 | },
48 | instantMove: true,
49 | },
50 | dropdown: {
51 | handleResize: false,
52 | },
53 | },
54 | }, options.vtooltip))
55 |
56 | Vue.use(VueResize)
57 |
58 | Vue.component('VueButton', VueButton)
59 | Vue.component('VueDisable', VueDisable)
60 | Vue.component('VueDropdown', VueDropdown)
61 | Vue.component('VueDropdownButton', VueDropdownButton)
62 | Vue.component('VueFormField', VueFormField)
63 | Vue.component('VueGroup', VueGroup)
64 | Vue.component('VueGroupButton', VueGroupButton)
65 | Vue.component('VueIcon', VueIcon)
66 | Vue.component('VueInput', VueInput)
67 | Vue.component('VueLoadingBar', VueLoadingBar)
68 | Vue.component('VueLoadingIndicator', VueLoadingIndicator)
69 | Vue.component('VueModal', VueModal)
70 | Vue.component('VueSelect', VueSelect)
71 | Vue.component('VueSelectButton', VueSelectButton)
72 | Vue.component('VueSwitch', VueSwitch)
73 | Vue.component('VueTab', VueTab)
74 | Vue.component('VueTabs', VueTabs)
75 | Vue.component('VueTypeAhead', VueTypeAhead)
76 | }
77 |
78 | const plugin = {
79 | // eslint-disable-next-line no-undef
80 | version: VERSION,
81 | install,
82 | }
83 |
84 | export default plugin
85 |
86 | function mergeOptions (to, from) {
87 | for (const key in from) {
88 | if (to[key] && from[key] && typeof to[key] === 'object' && typeof from[key] === 'object') {
89 | mergeOptions(to[key], from[key])
90 | } else {
91 | to[key] = from[key]
92 | }
93 | }
94 | return to
95 | }
96 |
97 | // Auto-install
98 | let GlobalVue = null
99 | if (typeof window !== 'undefined') {
100 | GlobalVue = window.Vue
101 | } else if (typeof global !== 'undefined') {
102 | GlobalVue = global.Vue
103 | }
104 | if (GlobalVue) {
105 | GlobalVue.use(plugin)
106 | }
107 |
--------------------------------------------------------------------------------
/src/mixins/CoupledChild.js:
--------------------------------------------------------------------------------
1 | /**
2 | * (Use with the CoupleParent mixin)
3 | * This mixin should be used on children components of a component implementing the CoupledParent mixin.
4 | * @param {string} name Name of the injection
5 | */
6 | export default function (name) {
7 | // @vue/component
8 | return {
9 | inject: [
10 | name,
11 | ],
12 |
13 | computed: {
14 | active () {
15 | return this[name].activeChild === this.$_couplingProxy
16 | },
17 | },
18 |
19 | created () {
20 | const proxy = this.$_couplingProxy = {}
21 | for (const key in this.$data) {
22 | if (key.charAt(0) === '$' || key.charAt(0) === '_') continue
23 | Object.defineProperty(proxy, key, {
24 | enumerable: true,
25 | configurable: false,
26 | get: () => this.$data[key],
27 | })
28 | }
29 | for (const key in this.$props) {
30 | if (key.charAt(0) === '$' || key.charAt(0) === '_') continue
31 | Object.defineProperty(proxy, key, {
32 | enumerable: true,
33 | configurable: false,
34 | get: () => this.$props[key],
35 | })
36 | }
37 | Object.defineProperty(proxy, '$slots', {
38 | enumerable: false,
39 | configurable: false,
40 | get: () => this.$slots,
41 | })
42 | this[name].$_addCoupledChild(proxy)
43 | },
44 |
45 | beforeDestroy () {
46 | this[name].$_removeCoupledChild(this.$_couplingProxy)
47 | },
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/mixins/CoupledParent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * (Use with the CoupledChild mixin)
3 | * Mixin allowing the automatic collection of children while preserving the virtual dom children order at all times.
4 | * Useful for creating tabs-style component, when we need to replicate the order of the children to display
5 | * a group of button (tab strip).
6 | * @param {string} name Name of the injection
7 | */
8 | export default function (name) {
9 | // @vue/component
10 | return {
11 | provide () {
12 | const proxy = {}
13 | Object.defineProperty(proxy, 'activeChild', {
14 | get: () => this.activeChild,
15 | })
16 | proxy.$_addCoupledChild = this.$_addCoupledChild.bind(this)
17 | proxy.$_removeCoupledChild = this.$_removeCoupledChild.bind(this)
18 | return {
19 | [name]: proxy,
20 | }
21 | },
22 |
23 | props: {
24 | childIndex: {
25 | default: 0,
26 | },
27 | },
28 |
29 | data () {
30 | return {
31 | children: [],
32 | activeChildIndex: parseInt(this.childIndex) || 0,
33 | }
34 | },
35 |
36 | computed: {
37 | activeChild () {
38 | if (this.activeChildIndex < this.children.length) {
39 | return this.children[this.activeChildIndex]
40 | }
41 | },
42 | },
43 |
44 | watch: {
45 | childIndex (val) {
46 | this.activateChild(parseInt(val) || 0, true)
47 | },
48 | },
49 |
50 | methods: {
51 | /**
52 | * Activates a child.
53 | * @param {number} index Index of child to activate
54 | * @param {boolean} external Indicates if the activation comes from an external source (like props)
55 | */
56 | activateChild (index, external = false) {
57 | const oldIndex = this.activeChildIndex
58 | if (index < 0) {
59 | index = 0
60 | } else if (index >= this.children.length) {
61 | index = this.children.length - 1
62 | }
63 | this.activeChildIndex = index
64 | this.$emit('update:childIndex', index)
65 | this.childActivated(index, oldIndex, external)
66 | },
67 |
68 | /**
69 | * Hook called when a child is activated.
70 | * @param {number} index Index of the activated child
71 | * @param {number} oldIndex Index of the previously activated child
72 | * @param {boolean} external Indicates if the activation comes from an external source (like props)
73 | */
74 | childActivated (index, oldIndex, external) {
75 | // Override this in component
76 | },
77 |
78 | /**
79 | * Add a child component while preserving its order in the children list.
80 | * @param {object} proxyVm Vue instance
81 | */
82 | $_addCoupledChild (proxyVm) {
83 | // Guard
84 | if (this.$slots && this.$slots.default) {
85 | // We need to wait for the instances creation
86 | this.$nextTick(() => {
87 | // We need to get the components in the slot
88 | const childComponents = this.$slots.default.reduce((list, vnode) => {
89 | const coupledChild = findCoupledChild(vnode)
90 | if (coupledChild) {
91 | list.push(coupledChild.$_couplingProxy)
92 | }
93 | return list
94 | }, [])
95 | // List has the child component in the right order
96 | // We can now register the child component in the right place
97 | const index = childComponents.indexOf(proxyVm)
98 | // Add child
99 | if (index !== -1) {
100 | this.children.splice(index, 0, proxyVm)
101 | // Hook
102 | this.$_updateChildren('add', index, proxyVm)
103 | }
104 | })
105 | }
106 | },
107 |
108 | /**
109 | * Removes a child component. Automatically activates the next remaining component.
110 | * @param {object} proxyVm Vue instance
111 | */
112 | $_removeCoupledChild (proxyVm) {
113 | const index = this.children.indexOf(proxyVm)
114 | // Remove child
115 | if (index !== -1) {
116 | this.children.splice(index, 1)
117 | }
118 | // Hook
119 | this.$_updateChildren('remove', index, proxyVm)
120 | },
121 |
122 | /**
123 | * Hook called when an operation is processed. It will intelligently activate a child if needed.
124 | * @param {string} operation Name of the operation. Can be 'add' or 'remove'
125 | * @param {number} index Index of the related child.
126 | * @param {object} proxyVm Related child Vue instance
127 | */
128 | $_updateChildren (operation, index, proxyVm) {
129 | if (operation === 'add') {
130 | // If the child was added before the currently active one,
131 | // we need to move the selection to the right
132 | if (index <= this.activeChildIndex) {
133 | this.activateChild(this.activeChildIndex + 1)
134 | }
135 | // Default when there is only one child
136 | if (this.children.length === 1) {
137 | this.activateChild(0)
138 | }
139 | } else if (operation === 'remove') {
140 | // If we remove a child before the currently active one,
141 | // we need to move the selection to the left
142 | if (index <= this.activeChildIndex) {
143 | this.activateChild(this.activeChildIndex - 1)
144 | }
145 | }
146 | },
147 | },
148 | }
149 | }
150 |
151 | function findCoupledChild (vnode) {
152 | const vm = vnode.child
153 | if (vm) {
154 | if (vm.$_couplingProxy) {
155 | return vm
156 | } else {
157 | return findCoupledChildInChildren([...vm.$children])
158 | }
159 | }
160 | }
161 |
162 | // Breadth-first search
163 | function findCoupledChildInChildren (queue) {
164 | let child
165 | while ((child = queue.shift())) {
166 | if (child.$_couplingProxy) {
167 | return child
168 | } else {
169 | queue.push(...child.$children)
170 | }
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/src/mixins/DisableScroll.js:
--------------------------------------------------------------------------------
1 | let count = 0
2 |
3 | function getScrollingElements () {
4 | return document.querySelectorAll('.vue-ui-disable-scroll, body')
5 | }
6 |
7 | function updateScroll () {
8 | if (count === 0) {
9 | getScrollingElements().forEach(el => el.classList.remove('vue-ui-no-scroll'))
10 | } else if (count === 1) {
11 | getScrollingElements().forEach(el => el.classList.add('vue-ui-no-scroll'))
12 | }
13 | }
14 |
15 | export default {
16 | mounted () {
17 | count++
18 | updateScroll()
19 | },
20 |
21 | beforeDestroy () {
22 | count--
23 | updateScroll()
24 | },
25 | }
26 |
--------------------------------------------------------------------------------
/src/mixins/DisabledChild.js:
--------------------------------------------------------------------------------
1 | /**
2 | * (Use with the DisabledParent mixin)
3 | * This mixin should be implemented on all components that can be disabled.
4 | */
5 | // @vue/component
6 | export default {
7 | inject: {
8 | VueDisableMixin: {
9 | default: null,
10 | },
11 | },
12 |
13 | props: {
14 | disabled: {
15 | type: Boolean,
16 | default: false,
17 | },
18 | },
19 |
20 | computed: {
21 | finalDisabled () {
22 | return this.disabled || (this.VueDisableMixin && this.VueDisableMixin.data.value)
23 | },
24 | },
25 | }
26 |
--------------------------------------------------------------------------------
/src/mixins/DisabledParent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * (Use with the DisabledChild mixin)
3 | * Allow disabling an entire tree of components implementing the DisabledChild mixin.
4 | */
5 | // @vue/component
6 | export default {
7 | provide () {
8 | return {
9 | VueDisableMixin: {
10 | data: this.injectedDisableData,
11 | },
12 | }
13 | },
14 |
15 | props: {
16 | disabled: {
17 | type: Boolean,
18 | default: false,
19 | },
20 | },
21 |
22 | data () {
23 | return {
24 | injectedDisableData: {
25 | value: this.disabled,
26 | },
27 | }
28 | },
29 |
30 | watch: {
31 | disabled (value, oldValue) {
32 | if (value !== oldValue) this.injectedDisableData.value = value
33 | },
34 | },
35 | }
36 |
--------------------------------------------------------------------------------
/src/style/animation.styl:
--------------------------------------------------------------------------------
1 | // Focus
2 |
3 | @keyframes vue-ui-focus
4 | $color = $vue-ui-accent-500
5 | 0%
6 | border-color $color
7 | box-shadow 0 0 20px rgba($color, 2)
8 | 100%
9 | border-color rgba($color, .6)
10 | box-shadow 0 0 4px rgba($color, .5)
11 |
12 | @keyframes vue-ui-focus-dark
13 | $color = $vue-ui-accent-300
14 | 0%
15 | border-color $color
16 | box-shadow 0 0 20px rgba($color, 2)
17 | 100%
18 | border-color rgba($color, .6)
19 | box-shadow 0 0 4px rgba($color, .5)
20 |
21 | // Slide
22 |
23 | vue-ui-slide($direction, $offset)
24 | if $direction == bottom
25 | $transform = "translateY(%s)" % $offset
26 | else if $direction == top
27 | $transform = "translateY(-%s)" % $offset
28 | else if $direction == left
29 | $transform = "translateX(-%s)" % $offset
30 | else if $direction == right
31 | $transform = "translateX(%s)" % $offset
32 | @keyframes vue-ui-slide-from-{$direction}
33 | 0%
34 | transform $transform
35 | 100%
36 | transform none
37 | @keyframes vue-ui-slide-to-{$direction}
38 | 0%
39 | transform none
40 | 100%
41 | transform $transform
42 |
43 | $offset = 6px
44 | vue-ui-slide(bottom, $offset)
45 | vue-ui-slide(top, $offset)
46 | vue-ui-slide(left, $offset)
47 | vue-ui-slide(right, $offset)
48 |
49 | // Fade
50 |
51 | .vue-ui-fade-enter-active,
52 | .vue-ui-fade-leave-active
53 | transition opacity .15s linear
54 |
55 | .vue-ui-fade-enter,
56 | .vue-ui-fade-leave-to
57 | opacity 0
58 |
--------------------------------------------------------------------------------
/src/style/base.styl:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700,700i')
2 |
3 | @import "./imports"
4 | @import "./animation"
5 | @import "./tooltip"
6 |
7 | html
8 | background $vue-ui-white
9 |
10 | body
11 | font-size 16px
12 | font-family 'Roboto', 'Avenir', Helvetica, Arial, sans-serif
13 | -webkit-font-smoothing antialiased
14 | -moz-osx-font-smoothing grayscale
15 | color $vue-ui-gray-800
16 | margin 0
17 |
18 | .vue-ui-dark-mode
19 | color $vue-ui-white
20 | background $vue-ui-black
21 | body
22 | color @color
23 |
24 | .vue-ui-high-contrast
25 | background black
26 |
27 | hr
28 | border none
29 | height 1px
30 | background $vue-ui-primary-100
31 |
32 | a
33 | color $vue-ui-primary-500
34 | text-decoration none
35 | .vue-ui-icon
36 | svg
37 | fill @color
38 |
39 | h1, h2, h3, h4, h5, h6
40 | font-weight 300
41 | margin 24px 0 8px
42 | &:first-child
43 | margin-top 0
44 |
45 | h1
46 | font-size 42px
47 |
48 | h2
49 | font-size 32px
50 |
51 | h3
52 | font-size 26px
53 |
54 | h4
55 | font-size 22px
56 |
57 | h5
58 | font-size 18px
59 |
60 | h6
61 | font-size 16px
62 |
63 | p
64 | margin 0 0 8px
65 |
66 | ul
67 | margin 4px 0
68 |
69 | .vue-ui-no-scroll
70 | overflow hidden
71 |
72 | .vue-ui-spacer
73 | flex auto 1 1 !important
74 | width 0
75 | height 0
76 |
77 | .vue-ui-empty
78 | color rgba($vue-ui-gray-800, .5)
79 | padding 24px
80 | text-align center
81 | box-sizing border-box
82 | .vue-ui-icon
83 | svg
84 | fill @color
85 | .vue-ui-dark-mode &
86 | color rgba($vue-ui-white, .5)
87 |
88 | .vue-ui-text
89 | &.banner
90 | padding 12px
91 | display flex
92 | align-items center
93 | border-radius $br
94 | > .vue-ui-icon
95 | flex auto 0 0
96 | &:first-child
97 | margin-right 10px
98 | &.primary
99 | vue-ui-text-colors($vue-ui-primary-500)
100 | &.accent
101 | vue-ui-text-colors($vue-ui-accent-500)
102 | &.danger
103 | vue-ui-text-colors($vue-ui-danger-500)
104 | &.warning
105 | vue-ui-text-colors($vue-ui-warning-500)
106 | &.info
107 | vue-ui-text-colors($vue-ui-info-500)
108 | &.success
109 | vue-ui-text-colors($vue-ui-primary-500)
110 |
111 | .vue-ui-grid
112 | display grid
113 | &.default-gap
114 | grid-gap 12px
115 | &.big-gap
116 | grid-gap 24px
117 | for n in (1..10)
118 | &.col-{n}
119 | grid-template-columns repeat(n, 1fr)
120 |
121 | .span-{n}
122 | grid-column span n
123 |
124 | ::-webkit-scrollbar
125 | width 10px
126 | height @width
127 | ::-webkit-scrollbar-track-piece
128 | background transparent
129 | ::-webkit-scrollbar-track:hover
130 | background rgba($vue-ui-gray-600, .05)
131 | .vue-ui-dark-mode &
132 | background rgba($vue-ui-gray-600, .1)
133 | ::-webkit-scrollbar-thumb
134 | background-color $vue-ui-gray-300
135 | border 3px solid transparent
136 | background-clip padding-box
137 | border-radius 5px
138 | &:hover
139 | background-color $vue-ui-gray-600
140 | .vue-ui-dark-mode &
141 | background-color $vue-ui-gray-800
142 | &:hover
143 | background-color $vue-ui-gray-500
144 |
145 | .vue-ui-dark-mode
146 | scrollbar-color $vue-ui-gray-800 $vue-ui-black
147 |
148 | .vue-ui-high-contrast
149 | :focus
150 | outline cyan 2px solid !important
151 |
152 | // Icon
153 |
154 | .vue-ui-icon
155 | display inline-block
156 | width 18px
157 | height @width
158 | vertical-align bottom
159 | svg
160 | width 100%
161 | height 100%
162 | fill $vue-ui-gray-800
163 | pointer-events none
164 |
165 | .vue-ui-dark-mode &
166 | svg
167 | fill $vue-ui-white
168 |
169 | &.primary
170 | svg
171 | fill $vue-ui-primary-500
172 | &.accent
173 | svg
174 | fill $vue-ui-accent-500
175 | &.danger
176 | svg
177 | fill $vue-ui-danger-500
178 | &.warning
179 | svg
180 | fill $vue-ui-warning-500
181 | &.info
182 | svg
183 | fill $vue-ui-info-500
184 | &.success
185 | svg
186 | fill $vue-ui-primary-500
187 |
188 | &.top
189 | position relative
190 | top -.06rem
191 |
192 | // Size
193 | &.small
194 | width 12px
195 | height @width
196 | &.medium
197 | width 20px
198 | height @width
199 | &.big
200 | width 24px
201 | height @width
202 | &.large
203 | width 32px
204 | height @width
205 | &.huge
206 | width 42px
207 | height @width
208 | &.gigantic
209 | width 64px
210 | height @width
211 |
212 | // Loading bar
213 |
214 | colors($foreground, $background)
215 | background $background
216 | .bar
217 | background $foreground
218 |
219 | .vue-ui-loading-bar
220 | height 3px
221 | position relative
222 |
223 | .bar
224 | height 100%
225 |
226 | colors($vue-ui-gray-800, $vue-ui-primary-100)
227 | .vue-ui-dark-mode &
228 | colors($vue-ui-gray-600, $vue-ui-gray-800)
229 |
230 | &.primary
231 | colors($vue-ui-primary-500, $vue-ui-primary-100)
232 | .vue-ui-dark-mode &
233 | colors($vue-ui-primary-500, $vue-ui-gray-800)
234 |
235 | &.accent
236 | colors($vue-ui-accent-500, $vue-ui-primary-100)
237 | .vue-ui-dark-mode &
238 | colors($vue-ui-accent-300, $vue-ui-gray-800)
239 |
240 | &.unknown
241 | .bar
242 | position absolute
243 | top 0
244 | animation bar-animation .8s infinite linear
245 |
246 | &.ghost
247 | height 0
248 | z-index 300
249 | background transparent
250 | .bar
251 | height 3px
252 |
253 | @keyframes bar-animation
254 | 0%
255 | left 0
256 | right 100%
257 | 50%
258 | left 0
259 | right 0
260 | 100%
261 | left 100%
262 | right 0
263 |
264 | // Loading indicator
265 |
266 | colors($color)
267 | border-color rgba($color, .1)
268 | border-right-color $color
269 |
270 | .vue-ui-loading-indicator
271 | display flex
272 | &.inline
273 | display inline-flex
274 | flex-direction column
275 | box-center()
276 |
277 | > .animation
278 | animation rotating .7s linear infinite
279 | width 16px
280 | height @width
281 | border-radius 50%
282 | border transparent 2px solid
283 | colors($vue-ui-gray-800)
284 | .vue-ui-dark-mode &
285 | colors($vue-ui-gray-600)
286 | &.primary
287 | > .animation
288 | colors($vue-ui-primary-500)
289 | &.accent
290 | > .animation
291 | colors($vue-ui-accent-500)
292 | .vue-ui-dark-mode &
293 | colors($vue-ui-accent-300)
294 | &.small
295 | > .animation
296 | width 10px
297 | height @width
298 | &.big
299 | > .animation
300 | width 24px
301 | height @width
302 | border-width 3px
303 |
304 | .vue-ui-high-contrast &
305 | > .animation
306 | border-width 4px
307 |
308 | &.overlay
309 | position absolute
310 | top 0
311 | bottom 0
312 | left 0
313 | right 0
314 | z-index 1
315 | > .animation
316 | margin-bottom 32px
317 | &:not(.transparent)
318 | background rgba($vue-ui-white, .95)
319 | .vue-ui-dark-mode &
320 | background rgba($vue-ui-gray-900, .95)
321 | &.fixed
322 | position fixed
323 |
324 | @keyframes rotating
325 | 0%
326 | transform rotate(0)
327 | 100%
328 | transform rotate(360deg)
--------------------------------------------------------------------------------
/src/style/colors.styl:
--------------------------------------------------------------------------------
1 | $vue-ui-white = #ffffff
2 | $vue-ui-black = #0b1015
3 | // Gray
4 | $vue-ui-gray-900 = #1d2935
5 | $vue-ui-gray-800 = #2c3e50
6 | $vue-ui-gray-700 = #3e5770
7 | $vue-ui-gray-600 = #4f6f7f
8 | $vue-ui-gray-500 = #809fae
9 | $vue-ui-gray-400 = #93b0be
10 | $vue-ui-gray-300 = #b6c6ce
11 | $vue-ui-gray-200 = #c8d3d9
12 | $vue-ui-gray-100 = #e0e5e7
13 | // Primary
14 | $vue-ui-primary-900 = #034124
15 | $vue-ui-primary-800 = #085e37
16 | $vue-ui-primary-700 = #13794a
17 | $vue-ui-primary-600 = #299f69
18 | $vue-ui-primary-500 = #42b983
19 | $vue-ui-primary-400 = #56cd96
20 | $vue-ui-primary-300 = #89deb7
21 | $vue-ui-primary-200 = #abeacd
22 | $vue-ui-primary-100 = #e0f8ed
23 | // Accent
24 | $vue-ui-accent-900 = #350066
25 | $vue-ui-accent-800 = #4f0098
26 | $vue-ui-accent-700 = #6806c1
27 | $vue-ui-accent-600 = #8929e3
28 | $vue-ui-accent-500 = #a44cf6
29 | $vue-ui-accent-400 = #b96dff
30 | $vue-ui-accent-300 = #c88eff
31 | $vue-ui-accent-200 = #d7adff
32 | $vue-ui-accent-100 = #e6ccff
33 | // Danger
34 | $vue-ui-danger-900 = #500000
35 | $vue-ui-danger-800 = #850505
36 | $vue-ui-danger-700 = #ac0d0d
37 | $vue-ui-danger-600 = #cd1b1b
38 | $vue-ui-danger-500 = #e83030
39 | $vue-ui-danger-400 = #f44747
40 | $vue-ui-danger-300 = #ff6565
41 | $vue-ui-danger-200 = #ff9494
42 | $vue-ui-danger-100 = #ffcaca
43 | // Warning
44 | $vue-ui-warning-900 = #702200
45 | $vue-ui-warning-800 = #943800
46 | $vue-ui-warning-700 = #b54d01
47 | $vue-ui-warning-600 = #c85900
48 | $vue-ui-warning-500 = #ea6e00
49 | $vue-ui-warning-400 = #ff8915
50 | $vue-ui-warning-300 = #ffa733
51 | $vue-ui-warning-200 = #ffc45e
52 | $vue-ui-warning-100 = #ffe6b0
53 | // Info
54 | $vue-ui-info-900 = #004576
55 | $vue-ui-info-800 = #006294
56 | $vue-ui-info-700 = #007db1
57 | $vue-ui-info-600 = #0098c4
58 | $vue-ui-info-500 = #03c2e6
59 | $vue-ui-info-400 = #74e0ed
60 | $vue-ui-info-300 = #9ae6ef
61 | $vue-ui-info-200 = #bceef1
62 | $vue-ui-info-100 = #e3f5f6
63 |
64 | // Legacy
65 | $vue-ui-color-light = #fff
66 | $vue-ui-color-light-neutral = #e4f5ef
67 | $vue-ui-color-dark = #2c3e50
68 | $vue-ui-color-dark-neutral = #4f6f7f
69 | $vue-ui-color-darker = #1d2935
70 | $vue-ui-color-almost-black = #0b1015
71 | $vue-ui-color-primary = #42b983
72 | $vue-ui-color-accent = #6806c1
73 | $vue-ui-color-accent-light = lighten($vue-ui-color-accent, 60%)
74 | $vue-ui-color-danger = #e83030
75 | $vue-ui-color-warning = #ea6e00
76 | $vue-ui-color-info = #03c2e6
77 | $vue-ui-color-success = #42b983
78 |
--------------------------------------------------------------------------------
/src/style/imports.styl:
--------------------------------------------------------------------------------
1 | @import "./md-colors"
2 | @import "./colors"
3 | @import "./vars"
4 | @import "./mixins"
5 |
--------------------------------------------------------------------------------
/src/style/md-colors.styl:
--------------------------------------------------------------------------------
1 | $md-red =#f44336;
2 | $md-red-50 =#ffebee;
3 | $md-red-100 =#ffcdd2;
4 | $md-red-200 =#ef9a9a;
5 | $md-red-300 =#e57373;
6 | $md-red-400 =#ef5350;
7 | $md-red-500 =#f44336;
8 | $md-red-600 =#e53935;
9 | $md-red-700 =#d32f2f;
10 | $md-red-800 =#c62828;
11 | $md-red-900 =#b71c1c;
12 | $md-red-a100 =#ff8a80;
13 | $md-red-a200 =#ff5252;
14 | $md-red-a400 =#ff1744;
15 | $md-red-a700 =#d50000;
16 |
17 | $md-pink =#e91e63;
18 | $md-pink-50 =#fce4ec;
19 | $md-pink-100 =#f8bbd0;
20 | $md-pink-200 =#f48fb1;
21 | $md-pink-300 =#f06292;
22 | $md-pink-400 =#ec407a;
23 | $md-pink-500 =#e91e63;
24 | $md-pink-600 =#d81b60;
25 | $md-pink-700 =#c2185b;
26 | $md-pink-800 =#ad1457;
27 | $md-pink-900 =#880e4f;
28 | $md-pink-a100 =#ff80ab;
29 | $md-pink-a200 =#ff4081;
30 | $md-pink-a400 =#f50057;
31 | $md-pink-a700 =#c51162;
32 |
33 | $md-purple =#9c27b0;
34 | $md-purple-50 =#f3e5f5;
35 | $md-purple-100 =#e1bee7;
36 | $md-purple-200 =#ce93d8;
37 | $md-purple-300 =#ba68c8;
38 | $md-purple-400 =#ab47bc;
39 | $md-purple-500 =#9c27b0;
40 | $md-purple-600 =#8e24aa;
41 | $md-purple-700 =#7b1fa2;
42 | $md-purple-800 =#6a1b9a;
43 | $md-purple-900 =#4a148c;
44 | $md-purple-a100 =#ea80fc;
45 | $md-purple-a200 =#e040fb;
46 | $md-purple-a400 =#d500f9;
47 | $md-purple-a700 =#aa00ff;
48 |
49 | $md-deep-purple =#673ab7;
50 | $md-deep-purple-50 =#ede7f6;
51 | $md-deep-purple-100 =#d1c4e9;
52 | $md-deep-purple-200 =#b39ddb;
53 | $md-deep-purple-300 =#9575cd;
54 | $md-deep-purple-400 =#7e57c2;
55 | $md-deep-purple-500 =#673ab7;
56 | $md-deep-purple-600 =#5e35b1;
57 | $md-deep-purple-700 =#512da8;
58 | $md-deep-purple-800 =#4527a0;
59 | $md-deep-purple-900 =#311b92;
60 | $md-deep-purple-a100 =#b388ff;
61 | $md-deep-purple-a200 =#7c4dff;
62 | $md-deep-purple-a400 =#651fff;
63 | $md-deep-purple-a700 =#6200ea;
64 |
65 | $md-indigo =#3f51b5;
66 | $md-indigo-50 =#e8eaf6;
67 | $md-indigo-100 =#c5cae9;
68 | $md-indigo-200 =#9fa8da;
69 | $md-indigo-300 =#7986cb;
70 | $md-indigo-400 =#5c6bc0;
71 | $md-indigo-500 =#3f51b5;
72 | $md-indigo-600 =#3949ab;
73 | $md-indigo-700 =#303f9f;
74 | $md-indigo-800 =#283593;
75 | $md-indigo-900 =#1a237e;
76 | $md-indigo-a100 =#8c9eff;
77 | $md-indigo-a200 =#536dfe;
78 | $md-indigo-a400 =#3d5afe;
79 | $md-indigo-a700 =#304ffe;
80 |
81 | $md-blue =#2196f3;
82 | $md-blue-50 =#e3f2fd;
83 | $md-blue-100 =#bbdefb;
84 | $md-blue-200 =#90caf9;
85 | $md-blue-300 =#64b5f6;
86 | $md-blue-400 =#42a5f5;
87 | $md-blue-500 =#2196f3;
88 | $md-blue-600 =#1e88e5;
89 | $md-blue-700 =#1976d2;
90 | $md-blue-800 =#1565c0;
91 | $md-blue-900 =#0d47a1;
92 | $md-blue-a100 =#82b1ff;
93 | $md-blue-a200 =#448aff;
94 | $md-blue-a400 =#2979ff;
95 | $md-blue-a700 =#2962ff;
96 |
97 | $md-light-blue =#03a9f4;
98 | $md-light-blue-50 =#e1f5fe;
99 | $md-light-blue-100 =#b3e5fc;
100 | $md-light-blue-200 =#81d4fa;
101 | $md-light-blue-300 =#4fc3f7;
102 | $md-light-blue-400 =#29b6f6;
103 | $md-light-blue-500 =#03a9f4;
104 | $md-light-blue-600 =#039be5;
105 | $md-light-blue-700 =#0288d1;
106 | $md-light-blue-800 =#0277bd;
107 | $md-light-blue-900 =#01579b;
108 | $md-light-blue-a100 =#80d8ff;
109 | $md-light-blue-a200 =#40c4ff;
110 | $md-light-blue-a400 =#00b0ff;
111 | $md-light-blue-a700 =#0091ea;
112 |
113 | $md-cyan =#00bcd4;
114 | $md-cyan-50 =#e0f7fa;
115 | $md-cyan-100 =#b2ebf2;
116 | $md-cyan-200 =#80deea;
117 | $md-cyan-300 =#4dd0e1;
118 | $md-cyan-400 =#26c6da;
119 | $md-cyan-500 =#00bcd4;
120 | $md-cyan-600 =#00acc1;
121 | $md-cyan-700 =#0097a7;
122 | $md-cyan-800 =#00838f;
123 | $md-cyan-900 =#006064;
124 | $md-cyan-a100 =#84ffff;
125 | $md-cyan-a200 =#18ffff;
126 | $md-cyan-a400 =#00e5ff;
127 | $md-cyan-a700 =#00b8d4;
128 |
129 | $md-teal =#009688;
130 | $md-teal-50 =#e0f2f1;
131 | $md-teal-100 =#b2dfdb;
132 | $md-teal-200 =#80cbc4;
133 | $md-teal-300 =#4db6ac;
134 | $md-teal-400 =#26a69a;
135 | $md-teal-500 =#009688;
136 | $md-teal-600 =#00897b;
137 | $md-teal-700 =#00796b;
138 | $md-teal-800 =#00695c;
139 | $md-teal-900 =#004d40;
140 | $md-teal-a100 =#a7ffeb;
141 | $md-teal-a200 =#64ffda;
142 | $md-teal-a400 =#1de9b6;
143 | $md-teal-a700 =#00bfa5;
144 |
145 | $md-green =#4caf50;
146 | $md-green-50 =#e8f5e9;
147 | $md-green-100 =#c8e6c9;
148 | $md-green-200 =#a5d6a7;
149 | $md-green-300 =#81c784;
150 | $md-green-400 =#66bb6a;
151 | $md-green-500 =#4caf50;
152 | $md-green-600 =#43a047;
153 | $md-green-700 =#388e3c;
154 | $md-green-800 =#2e7d32;
155 | $md-green-900 =#1b5e20;
156 | $md-green-a100 =#b9f6ca;
157 | $md-green-a200 =#69f0ae;
158 | $md-green-a400 =#00e676;
159 | $md-green-a700 =#00c853;
160 |
161 | $md-light-green =#8bc34a;
162 | $md-light-green-50 =#f1f8e9;
163 | $md-light-green-100 =#dcedc8;
164 | $md-light-green-200 =#c5e1a5;
165 | $md-light-green-300 =#aed581;
166 | $md-light-green-400 =#9ccc65;
167 | $md-light-green-500 =#8bc34a;
168 | $md-light-green-600 =#7cb342;
169 | $md-light-green-700 =#689f38;
170 | $md-light-green-800 =#558b2f;
171 | $md-light-green-900 =#33691e;
172 | $md-light-green-a100 =#ccff90;
173 | $md-light-green-a200 =#b2ff59;
174 | $md-light-green-a400 =#76ff03;
175 | $md-light-green-a700 =#64dd17;
176 |
177 | $md-lime =#cddc39;
178 | $md-lime-50 =#f9fbe7;
179 | $md-lime-100 =#f0f4c3;
180 | $md-lime-200 =#e6ee9c;
181 | $md-lime-300 =#dce775;
182 | $md-lime-400 =#d4e157;
183 | $md-lime-500 =#cddc39;
184 | $md-lime-600 =#c0ca33;
185 | $md-lime-700 =#afb42b;
186 | $md-lime-800 =#9e9d24;
187 | $md-lime-900 =#827717;
188 | $md-lime-a100 =#f4ff81;
189 | $md-lime-a200 =#eeff41;
190 | $md-lime-a400 =#c6ff00;
191 | $md-lime-a700 =#aeea00;
192 |
193 | $md-yellow =#ffeb3b;
194 | $md-yellow-50 =#fffde7;
195 | $md-yellow-100 =#fff9c4;
196 | $md-yellow-200 =#fff59d;
197 | $md-yellow-300 =#fff176;
198 | $md-yellow-400 =#ffee58;
199 | $md-yellow-500 =#ffeb3b;
200 | $md-yellow-600 =#fdd835;
201 | $md-yellow-700 =#fbc02d;
202 | $md-yellow-800 =#f9a825;
203 | $md-yellow-900 =#f57f17;
204 | $md-yellow-a100 =#ffff8d;
205 | $md-yellow-a200 =#ffff00;
206 | $md-yellow-a400 =#ffea00;
207 | $md-yellow-a700 =#ffd600;
208 |
209 | $md-amber =#ffc107;
210 | $md-amber-50 =#fff8e1;
211 | $md-amber-100 =#ffecb3;
212 | $md-amber-200 =#ffe082;
213 | $md-amber-300 =#ffd54f;
214 | $md-amber-400 =#ffca28;
215 | $md-amber-500 =#ffc107;
216 | $md-amber-600 =#ffb300;
217 | $md-amber-700 =#ffa000;
218 | $md-amber-800 =#ff8f00;
219 | $md-amber-900 =#ff6f00;
220 | $md-amber-a100 =#ffe57f;
221 | $md-amber-a200 =#ffd740;
222 | $md-amber-a400 =#ffc400;
223 | $md-amber-a700 =#ffab00;
224 |
225 | $md-orange =#ff9800;
226 | $md-orange-50 =#fff3e0;
227 | $md-orange-100 =#ffe0b2;
228 | $md-orange-200 =#ffcc80;
229 | $md-orange-300 =#ffb74d;
230 | $md-orange-400 =#ffa726;
231 | $md-orange-500 =#ff9800;
232 | $md-orange-600 =#fb8c00;
233 | $md-orange-700 =#f57c00;
234 | $md-orange-800 =#ef6c00;
235 | $md-orange-900 =#e65100;
236 | $md-orange-a100 =#ffd180;
237 | $md-orange-a200 =#ffab40;
238 | $md-orange-a400 =#ff9100;
239 | $md-orange-a700 =#ff6d00;
240 |
241 | $md-deep-orange =#ff5722;
242 | $md-deep-orange-50 =#fbe9e7;
243 | $md-deep-orange-100 =#ffccbc;
244 | $md-deep-orange-200 =#ffab91;
245 | $md-deep-orange-300 =#ff8a65;
246 | $md-deep-orange-400 =#ff7043;
247 | $md-deep-orange-500 =#ff5722;
248 | $md-deep-orange-600 =#f4511e;
249 | $md-deep-orange-700 =#e64a19;
250 | $md-deep-orange-800 =#d84315;
251 | $md-deep-orange-900 =#bf360c;
252 | $md-deep-orange-a100 =#ff9e80;
253 | $md-deep-orange-a200 =#ff6e40;
254 | $md-deep-orange-a400 =#ff3d00;
255 | $md-deep-orange-a700 =#dd2c00;
256 |
257 | $md-brown =#795548;
258 | $md-brown-50 =#efebe9;
259 | $md-brown-100 =#d7ccc8;
260 | $md-brown-200 =#bcaaa4;
261 | $md-brown-300 =#a1887f;
262 | $md-brown-400 =#8d6e63;
263 | $md-brown-500 =#795548;
264 | $md-brown-600 =#6d4c41;
265 | $md-brown-700 =#5d4037;
266 | $md-brown-800 =#4e342e;
267 | $md-brown-900 =#3e2723;
268 |
269 | $md-grey =#9e9e9e;
270 | $md-grey-50 =#fafafa;
271 | $md-grey-100 =#f5f5f5;
272 | $md-grey-200 =#eeeeee;
273 | $md-grey-300 =#e0e0e0;
274 | $md-grey-400 =#bdbdbd;
275 | $md-grey-500 =#9e9e9e;
276 | $md-grey-600 =#757575;
277 | $md-grey-700 =#616161;
278 | $md-grey-800 =#424242;
279 | $md-grey-900 =#212121;
280 |
281 | $md-blue-grey =#607d8b;
282 | $md-blue-grey-50 =#eceff1;
283 | $md-blue-grey-100 =#cfd8dc;
284 | $md-blue-grey-200 =#b0bec5;
285 | $md-blue-grey-300 =#90a4ae;
286 | $md-blue-grey-400 =#78909c;
287 | $md-blue-grey-500 =#607d8b;
288 | $md-blue-grey-600 =#546e7a;
289 | $md-blue-grey-700 =#455a64;
290 | $md-blue-grey-800 =#37474f;
291 | $md-blue-grey-900 =#263238;
292 |
293 | $md-black =#000000;
294 | $md-white =#ffffff;
295 |
--------------------------------------------------------------------------------
/src/style/mixins.styl:
--------------------------------------------------------------------------------
1 | ellipsis() {
2 | overflow: hidden;
3 | -ms-text-overflow: ellipsis;
4 | text-overflow: ellipsis;
5 | white-space: nowrap;
6 | }
7 |
8 | bounds($distance) {
9 | top: $distance;
10 | bottom: $distance;
11 | right: $distance;
12 | left: $distance;
13 | }
14 |
15 | overlay() {
16 | position: absolute;
17 | bounds(0);
18 | }
19 |
20 | flex-box() {
21 | display: flex;
22 |
23 | & > * {
24 | flex: auto 0 0;
25 | }
26 | }
27 |
28 | h-box() {
29 | flex-box();
30 | flex-direction: row;
31 | }
32 |
33 | v-box() {
34 | flex-box();
35 | flex-direction: column;
36 | }
37 |
38 | flex-control() {
39 | width: 0 !important;
40 | }
41 |
42 | box-center() {
43 | align-items: center;
44 | justify-content: center;
45 | }
46 |
47 | space-between-x($margin) {
48 | margin-right: $margin;
49 |
50 | &:last-child {
51 | margin-right: 0;
52 | }
53 | }
54 |
55 | space-between-y($margin) {
56 | margin-bottom: $margin;
57 |
58 | &:last-child {
59 | margin-bottom: 0;
60 | }
61 | }
62 |
63 | // Disable noisy browser styles
64 | disable-focus-styles()
65 | outline none
66 | -webkit-tap-highlight-color rgba(255, 255, 255, 0)
67 | &::-moz-focus-inner
68 | border 0
69 |
70 | // Buttons
71 |
72 | button-colors($foreground, $background)
73 | color $foreground
74 | background $background
75 | &:not(.ghost)
76 | &:hover,
77 | .vue-ui-dropdown.open .dropdown-trigger &
78 | background lighten($background, 25%)
79 | .vue-ui-dark-mode .vue-ui-dropdown.open .dropdown-trigger &
80 | background $vue-ui-gray-600
81 | color $vue-ui-white
82 | > .content
83 | > .button-icon
84 | svg
85 | fill $vue-ui-white
86 |
87 | &:hover
88 | .vue-ui-dark-mode .popover &
89 | background $vue-ui-gray-800 !important
90 | &:active
91 | background darken($background, 8%)
92 | > .content
93 | > .button-icon
94 | svg
95 | fill $foreground
96 | > .vue-ui-loading-indicator,
97 | > .content > .loading-secondary
98 | .animation
99 | border-right-color $foreground
100 | > .content > .tag-wrapper > .tag
101 | background $foreground
102 | color $background
103 | if $background is transparent
104 | color $vue-ui-white
105 | .vue-ui-dark-mode &
106 | color $vue-ui-gray-800 !important
107 | .vue-ui-high-contrast &
108 | background black !important
109 | color white !important
110 | &::before
111 | background $background
112 |
113 | &.vue-ui-dropdown-button
114 | background transparent
115 | &:not(:hover)
116 | color $vue-ui-gray-800
117 | .vue-ui-dark-mode &
118 | color $vue-ui-white !important
119 | > .content
120 | > .button-icon
121 | svg
122 | fill @color
123 | .vue-ui-dark-mode &
124 | fill $vue-ui-white !important
125 |
126 | button-transitions()
127 | transition background .1s, color .1s
128 | > .content
129 | > .button-icon
130 | svg
131 | transition fill .1s
132 |
133 | // Vue text
134 |
135 | vue-ui-text-colors($c)
136 | color $c
137 | .vue-ui-icon
138 | svg
139 | fill $c !important
140 | &.banner
141 | background lighten($c, 90%)
142 | .vue-ui-dark-mode &
143 | background darken($c, 60%)
144 |
--------------------------------------------------------------------------------
/src/style/tooltip.styl:
--------------------------------------------------------------------------------
1 | .v-popper--theme-tooltip
2 | $background = $vue-ui-gray-800
3 | $dark-background = $vue-ui-white
4 | $color = $vue-ui-white
5 | $dark-color = $vue-ui-gray-800
6 |
7 | font-size 14px
8 |
9 | .v-popper__inner
10 | background $background
11 | color $color
12 |
13 | .v-popper__arrow
14 | border-color $background
15 |
16 | .vue-ui-dark-mode &
17 | .v-popper__inner
18 | background $dark-background
19 | color $dark-color
20 |
21 | .v-popper__arrow
22 | border-color $dark-background
23 |
24 | .v-popper--theme-dropdown
25 | $background = $vue-ui-white
26 | $dark-background = $vue-ui-gray-900
27 | $color = $vue-ui-gray-800
28 | $dark-color = $vue-ui-white
29 |
30 | .v-popper__inner
31 | background $background
32 | color $color
33 | padding 4px 0
34 | box-shadow 0 0 3px rgba(black, .05), 0 10px 30px rgba(black, .1)
35 |
36 | .v-popper__arrow
37 | border-color $background
38 |
39 | .vue-ui-dark-mode &
40 | .v-popper__inner
41 | background $dark-background
42 | color $dark-color
43 |
44 | .v-popper__arrow
45 | border-color $dark-background
46 |
47 | &[data-popper-placement^='top']
48 | .v-popper__arrow
49 | filter drop-shadow(0 3px 3px rgba(black, .15))
50 | &[data-popper-placement^='bottom']
51 | .v-popper__arrow
52 | filter drop-shadow(0 -3px 3px rgba(black, .15))
53 | &[data-popper-placement^='left']
54 | .v-popper__arrow
55 | filter drop-shadow(3px 0 3px rgba(black, .15))
56 | &[data-popper-placement^='right']
57 | .v-popper__arrow
58 | filter drop-shadow(-3px 0 3px rgba(black, .15))
59 |
60 | // Animation
61 | &.v-popper__popper--show-to,
62 | &.v-popper__popper--hide-to
63 | > .v-popper__wrapper
64 | transition transform .12s ease-out
65 |
66 | &.v-popper__popper--show-from,
67 | &.v-popper__popper--hide-to
68 | &[data-popper-placement^='top']
69 | > .v-popper__wrapper
70 | transform translateY(6px)
71 | &[data-popper-placement^='bottom']
72 | > .v-popper__wrapper
73 | transform translateY(-6px)
74 | &[data-popper-placement^='left']
75 | > .v-popper__wrapper
76 | transform translateX(6px)
77 | &[data-popper-placement^='right']
78 | > .v-popper__wrapper
79 | transform translateX(-6px)
--------------------------------------------------------------------------------
/src/style/vars.styl:
--------------------------------------------------------------------------------
1 | $br = 3px
2 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 |
3 | module.exports = {
4 | lintOnSave: false,
5 |
6 | outputDir: './docs',
7 | publicPath: './',
8 |
9 | configureWebpack: {
10 | entry: {
11 | app: path.resolve(__dirname, './docs-src/main.js'),
12 | },
13 | resolve: {
14 | alias: {
15 | '@style': path.resolve(__dirname, './src/style/imports.styl'),
16 | '@': path.resolve(__dirname, './docs-src'),
17 | },
18 | },
19 | },
20 |
21 | chainWebpack: config => {
22 | config.module
23 | .rule('js')
24 | .include
25 | .add(path.resolve(__dirname, './docs-src'))
26 |
27 | config.module
28 | .rule('vue')
29 | .use('vue-loader')
30 | .loader('vue-loader')
31 | .tap(options => {
32 | options.compilerOptions.preserveWhitespace = true
33 | return options
34 | })
35 | },
36 | }
37 |
--------------------------------------------------------------------------------