├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── .markdownlint.json ├── .npmrc ├── .prettierrc ├── .stylelintignore ├── .travis.yml ├── .vcmrc ├── .vscode ├── extensions.json ├── settings.json └── tasks.json ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── components ├── base │ ├── apply-passive.js │ ├── auto-init.js │ ├── base-plugin.js │ ├── custom-button.js │ ├── custom-element.js │ ├── custom-event.js │ ├── custom-icon.js │ ├── custom-link.js │ ├── dispatch-event-mixin.js │ ├── dispatch-focus-mixin.js │ ├── index.js │ └── uniqueid-mixin.js ├── button │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-button-base.vue │ ├── mdc-button.vue │ ├── styles.scss │ └── test.spec.js ├── card │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-card-action-button.vue │ ├── mdc-card-action-buttons.vue │ ├── mdc-card-action-icon.vue │ ├── mdc-card-action-icons.vue │ ├── mdc-card-actions.vue │ ├── mdc-card-header.vue │ ├── mdc-card-media.vue │ ├── mdc-card-primary-action.vue │ ├── mdc-card-subtitle.vue │ ├── mdc-card-text.vue │ ├── mdc-card-title.vue │ ├── mdc-card.vue │ ├── styles.scss │ └── test.spec.js ├── checkbox │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-checkbox.vue │ ├── styles.scss │ └── test.spec.js ├── chips │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-chip-set.vue │ ├── mdc-chip.vue │ ├── styles.scss │ ├── test.spec.js │ └── test.spec.vue ├── dialog │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-dialog.vue │ ├── styles.scss │ └── test.spec.js ├── drawer │ ├── README.md │ ├── demo.html │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-drawer-divider.vue │ ├── mdc-drawer-header.vue │ ├── mdc-drawer-item.vue │ ├── mdc-drawer-layout.vue │ ├── mdc-drawer-list.vue │ ├── mdc-drawer.vue │ ├── mdc-permanent-drawer.vue │ ├── mdc-persistent-drawer.vue │ ├── mdc-temporary-drawer.vue │ ├── styles.scss │ ├── test.spec.js │ └── test.spec.vue ├── elevation │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-elevation.vue │ ├── styles.scss │ └── test.spec.js ├── entry.js ├── fab │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-fab.vue │ ├── styles.scss │ └── test.spec.js ├── grid-list │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-grid-list.vue │ ├── mdc-grid-tile.vue │ ├── styles.scss │ ├── test.spec.js │ └── test.spec.vue ├── icon-toggle │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-icon-toggle.vue │ ├── styles.scss │ └── test.spec.js ├── icon │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-icon.vue │ ├── styles.scss │ └── test.spec.js ├── index.js ├── layout-app │ ├── README.md │ ├── demo.html │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-layout-app.vue │ ├── styles.scss │ └── test.spec.js ├── layout-grid │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-layout-cell.vue │ ├── mdc-layout-grid.vue │ ├── mdc-layout-inner-grid.vue │ ├── styles.scss │ └── test.spec.js ├── linear-progress │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-linear-progress.vue │ ├── styles.scss │ └── test.spec.js ├── list │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-list-divider.vue │ ├── mdc-list-group-divider.vue │ ├── mdc-list-group-header.vue │ ├── mdc-list-group.vue │ ├── mdc-list-item.vue │ ├── mdc-list.vue │ ├── styles.scss │ ├── test.spec.js │ └── test.spec.vue ├── menu │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-menu-anchor.vue │ ├── mdc-menu-divider.vue │ ├── mdc-menu-item.vue │ ├── mdc-menu.vue │ ├── styles.scss │ └── test.spec.js ├── radio │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-radio.vue │ ├── styles.scss │ └── test.spec.js ├── ripple │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-ripple-base.js │ ├── mdc-ripple.vue │ ├── styles.scss │ └── test.spec.js ├── select │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-select-label.vue │ ├── mdc-select-line-ripple.vue │ ├── mdc-select-notched-outline.vue │ ├── mdc-select.vue │ ├── package-lock.json │ ├── styles.scss │ ├── test.spec.js │ └── test.spec.vue ├── slider │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-slider.vue │ ├── styles.scss │ └── test.spec.js ├── snackbar │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-snackbar.vue │ ├── styles.scss │ └── test.spec.js ├── styles.scss ├── switch │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-switch.vue │ ├── styles.scss │ └── test.spec.js ├── tabs │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-tab-bar.vue │ ├── mdc-tab.vue │ ├── styles.scss │ └── test.spec.js ├── textfield │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-textfield.vue │ ├── styles.scss │ └── test.spec.js ├── theme │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-theme.vue │ ├── styles.scss │ └── test.spec.js ├── toolbar │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-toolbar-icon.vue │ ├── mdc-toolbar-menu-icon.vue │ ├── mdc-toolbar-row.vue │ ├── mdc-toolbar-section.vue │ ├── mdc-toolbar-title.vue │ ├── mdc-toolbar.vue │ ├── styles.scss │ └── test.spec.js ├── top-app-bar │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-top-app-bar-action.vue │ ├── mdc-top-app-bar.vue │ ├── styles.scss │ └── test.spec.js ├── typography │ ├── README.md │ ├── demo.vue │ ├── entry.js │ ├── index.js │ ├── mdc-typography.js │ ├── styles.scss │ └── test.spec.js └── unit-test │ ├── index.js │ └── polyfills.js ├── demo ├── assets │ ├── card-16-9.jpg │ ├── component.svg │ ├── github-logo.svg │ ├── github-mark-32px.png │ ├── ic_button_24px.svg │ ├── ic_card_24px.svg │ ├── ic_component_24px.svg │ ├── ic_component_24px_white.svg │ ├── ic_dialog_24px.svg │ ├── ic_list_24px.svg │ ├── ic_menu_24px.svg │ ├── ic_progress_activity.svg │ ├── ic_radio_button_24px.svg │ ├── ic_responsive_layout_24px.svg │ ├── ic_ripple_24px.svg │ ├── ic_selection_control_24px.svg │ ├── ic_shadow_24px.svg │ ├── ic_side_navigation_24px.svg │ ├── ic_slider_24px.svg │ ├── ic_switch_24px.svg │ ├── ic_tabs_24px.svg │ ├── ic_text_field_24px.svg │ ├── ic_theme_24px.svg │ ├── ic_toast_24px.svg │ ├── ic_toolbar_24px.svg │ ├── ic_typography_24px.svg │ ├── logo.svg │ ├── mdc-logo.svg │ ├── tile-1-1.jpg │ ├── vue-awesome.png │ ├── vue-banner.png │ ├── vue-logo.-dark.png │ └── vue-logo.png ├── component.vue ├── doc.vue ├── drawer.vue ├── home.vue ├── index.html ├── index.vue ├── links.js ├── main.js ├── polyfill.js ├── routes.js ├── styles │ ├── _constant.scss │ ├── demo.scss │ ├── index.js │ └── markdown.scss ├── toolbar.vue └── utils │ ├── case.js │ └── index.js ├── docs ├── about.md ├── getting-started.md └── theming.md ├── jest.config.js ├── package-lock.json ├── package.json ├── rollup.config.js ├── static ├── .gitkeep ├── icon-128x128.png ├── icon-144x144.png ├── icon-152x152.png ├── icon-192x192.png ├── icon-384x384.png ├── icon-512x512.png ├── icon-72x72.png ├── icon-96x96.png └── logo.svg ├── stylelint.config.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "comments": true, 3 | "plugins": [ 4 | "transform-object-assign", 5 | "transform-object-rest-spread", 6 | "syntax-dynamic-import" 7 | ], 8 | "presets": [ 9 | ["env", { "modules": false }] 10 | ], 11 | "env": { 12 | "test": { 13 | "plugins": [ 14 | "transform-object-rest-spread", 15 | "syntax-dynamic-import", 16 | "transform-remove-strict-mode" 17 | ], 18 | "presets": [ 19 | ["env", { 20 | "targets": { "node": "current" }, 21 | }] 22 | ] 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [*.css] 15 | indent_style = space 16 | indent_size = 4 17 | 18 | [*.scss] 19 | indent_style = space 20 | indent_size = 4 21 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | test.spec.js 2 | test.spec.vue -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | "browser": true, 4 | "commonjs": true, 5 | "es6": true, 6 | "node": true, 7 | "jest": true 8 | }, 9 | plugins: [ 10 | "vue", 11 | "prettier" 12 | ], 13 | extends: [ 14 | "prettier", 15 | "eslint:recommended", 16 | "plugin:vue/recommended" 17 | ], 18 | "parserOptions": { 19 | "sourceType": "module", 20 | "parser": 'babel-eslint', 21 | "ecmaFeatures": { 22 | "jsx": true, 23 | } 24 | }, 25 | "rules": { 26 | "vue/name-property-casing": ["error", "kebab-case"], 27 | "vue/require-default-prop": "off", 28 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 1, 29 | 'no-console': process.env.NODE_ENV === 'production' ? 2 : 1, 30 | "prettier/prettier": "warn" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ** PLEASE READ THIS BEFORE FILING AN ISSUE ** 2 | 3 | vue-mdc-adapter is still under active development. You can see our current progress on [master](https://github.com/stasson/vue-mdc-adapter/tree/master). 4 | 5 | ## Bugs 6 | 7 | Follow the template below to ensure the quickest and most accurate response to your issue. 8 | 9 | ### What vue-mdc-adapter Version are you using? 10 | 11 | > Please be specific, e.g. _major.minor.patch_ 12 | 13 | ### What browser(s) is this bug affecting? 14 | 15 | > Please include the browser version. A user-agent string is also quite helpful. 16 | 17 | ### What OS are you using? 18 | 19 | > Please include the OS version. 20 | 21 | ### What are the steps to reproduce the bug? 22 | 23 | > Please write the steps which need to be taken in order to reproduce the bug. These steps should be 24 | > as detailed as possible, e.g. 25 | > 26 | > 1. Run the demo server 27 | > 2. localhost:8080/#/component/textfield 28 | > 3. Tab-focus on the first text field 29 | > 4. Observe the component's behavior 30 | > 31 | > We encourage you to use [CodePen](http://codepen.io/) to create a reproduction of 32 | > the issue. The less time it takes for us to repro the issue, the less time it takes to verify and 33 | > fix it! 34 | 35 | ### What is the expected behavior? 36 | 37 | > Please describe what the component/code should be doing that it's not. 38 | 39 | ### What is the actual behavior? 40 | 41 | > Please describe what the component/code is actually doing that's different from what it should be 42 | > doing. 43 | 44 | ### Any other information you believe would be useful? 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | public/ 4 | dist/ 5 | npm-debug.log* 6 | yarn-debug.log* 7 | yarn-error.log* 8 | test/unit/coverage 9 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "MD002": false, 3 | "MD013": false, 4 | "MD041": false 5 | } -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | message="v%s" 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "semi": false, 4 | "trailingComma":"none", 5 | "singleQuote": true, 6 | "overrides": [{ 7 | "files": "*.scss", 8 | "options": { 9 | "singleQuote": false 10 | } 11 | }] 12 | } 13 | -------------------------------------------------------------------------------- /.stylelintignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stasson/vue-mdc-adapter/7c0a6f6cfa41cb743e2fccc637bf55d5195f14b3/.stylelintignore -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | install: npm install 2 | before_install: 3 | - sudo apt-get install libgif-dev 4 | - npm install -g greenkeeper-lockfile@1 5 | language: node_js 6 | node_js: 7 | - '10' 8 | cache: 9 | directories: 10 | - node_modules 11 | branches: 12 | only: 13 | - /^v\d+\.\d+(\.\d+)?(-\S*)?$/ 14 | - /^greenkeeper/.*$/ 15 | - master 16 | - staging 17 | - dev 18 | before_script: greenkeeper-lockfile-update 19 | after_script: greenkeeper-lockfile-upload 20 | script: npm run ci 21 | deploy: 22 | - provider: npm 23 | skip_cleanup: true 24 | email: sebastien.tasson@gmail.com 25 | api_key: 26 | secure: Mot+1zVEid1MfZh7/HgPRMCjuzvyIlVMCe412AHSkYcnrYm8K/jmYAnLauGciHbsZR9phlrbu5xmdKjWmsMfjf9LYsBwEn9IlNUEWqhZ3DKfi87FN/PfV4lNrq1pgQJhtH1/bi656wFNAOG1JE2wjyEFknMN5I/rh33R7U5VnhubWBG5qdE4R54Z/AT1GTHgHd5NZISjxZsv2oLD35ktTpY/Z2zNXQ+eLdmOhOUN4jKr/0niq298fwdRG64lv2MikihJFM/88FYNQ/qIODnpS5b/vnxpYRHc6bHiWlZsVqzQXnA9xg/61ePm9+dTjSGSRmPkDzB+LFO8+XV7AcTzqoUrfSssU2JXcNqS/ZKlcJQcBPN7X6BAwHb7PXUuofSTIhIXv1xNfIpIh1w8aoLhDiUFIiWKo96B8Dy7Or44LeazM+vxVZCtm4aLpb1oFA0VLG2RffE7EbQmo8ehMeMLk2H/dy6tt0fdR+J0MI+ycS8FG7abKP0KZngvnT9ZbtzNow8rCYmGM+FSqiZVrL8MgBmJlsQifqPb5lUcBIEbIdnvCD/jSFMoKJckJKM/rZMy3untPD73dUQ55IjPyO4bn5cIxYBrdF1sU8oQnclNTT6norTImwCXQgqoHwh7aRVyfgNtPssczngb4DHn9Igi5yUIYOUHq9swU8D26Bi4TYM= 27 | on: 28 | repo: stasson/vue-mdc-adapter 29 | tags: true 30 | - edge: 31 | branch: v1.8.47 32 | provider: pages 33 | skip_cleanup: true 34 | github_token: $GH_TOKEN 35 | local_dir: public/vue-mdc-adapter 36 | on: 37 | repo: stasson/vue-mdc-adapter 38 | tags: true 39 | env: 40 | global: 41 | secure: ONJLXVJXS5wD1Xs3AiEutRPzBgAiY524E1EDVheutcTC5lVM9rEBDMgBy/WhvoEinI14sZ6x/+TV9wpW0iyk5BBnjHKAUgPsLS15o5TzLr053c66RYGO1HPKeojJAB0tBdtkeMGStA07jNGko8trm+jNUrGJs/HwvzZfPqjymynahEo4rL+l8ujOU/iUkG5FMtL2TbAZpPoF/V/i6kyST4CPBO8FOWJzZnJEtU7E8CFVnJtW9WReyCTlX27o+MXEz4KYr8OvUfzTNEQSpik5Ag5GoFzMeHWO76iDT/YzJ5EGrhybmVfYRClTuh4uw/52v0HBLQFO1biQQvltvjfWZ8uBMnwX6pL7Bl23ej+7/pvrEssRoeNdwUWkM46T52U/DZpjDREZVRuNcJgE83kpvYzR0sWrajWlAb+MTEaSEyxTFYqMWVPKXhIyJMQ2B6qDjNlDtygHS2gdn8LZcJMgmQgvUe+BFfilqaT7iy8SFUC6thf2a/t0Hc8dJThKhh6MjeyDAjVtuuRwmYXbW4baR7Bua3h9bGTTDBcMCYAMHYKnhmWIB6S/x1u47lgfixBrNo04IpM2dR454oWu429EBdtwdB4aXxBvWt6oKz9tvWhfkGzw1hcge9XEtLSjfbOkOOxHk/SZtpnF0GT5Skls/Y2khYmcjyYMm2cbx4SGIlU= 42 | -------------------------------------------------------------------------------- /.vcmrc: -------------------------------------------------------------------------------- 1 | { 2 | "types": ["feat", "fix", "docs", "style", "refactor", "perf", "test", "build", "ci", "chore", "revert"], 3 | "scope": { 4 | "required": false, 5 | "allowed": [ 6 | "button", 7 | "card", 8 | "checkbox", 9 | "dialog", 10 | "drawer", 11 | "fab", 12 | "form-field", 13 | "grid-list", 14 | "icon-toggle", 15 | "layout-grid", 16 | "linear-progress", 17 | "list", 18 | "menu", 19 | "radio", 20 | "select", 21 | "slider", 22 | "snackbar", 23 | "switch", 24 | "tabs", 25 | "textfield", 26 | "theme", 27 | "toolbar", 28 | "typography", 29 | "utils", 30 | "demo", 31 | "infra", 32 | "mdc", 33 | "package" 34 | ], 35 | "validate": false, 36 | "multiple": false 37 | }, 38 | "warnOnFail": true, 39 | "maxSubjectLength": 100, 40 | "subjectPattern": ".+", 41 | "subjectPatternErrorMsg": "subject does not match subject pattern!", 42 | "helpMessage": "%s\nNOTE: Please see angular's commit message guidelines (https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit) for information on how to format commit messages.", 43 | "autoFix": false 44 | } -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp 6 | "octref.vetur", 7 | "yzhang.markdown-all-in-one", 8 | "waderyan.nodejs-extension-pack", 9 | "EditorConfig.editorconfig", 10 | "esbenp.prettier-vscode" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "prettier.disableLanguages": [], 3 | "prettier.eslintIntegration": false, 4 | } 5 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "dev", 9 | "problemMatcher": [] 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017-present, Sebastien Tasson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /components/base/apply-passive.js: -------------------------------------------------------------------------------- 1 | let supportsPassive_ 2 | 3 | /** 4 | * Determine whether the current browser supports passive event listeners, and if so, use them. 5 | * @param {!Window=} globalObj 6 | * @param {boolean=} forceRefresh 7 | * @return {boolean|{passive: boolean}} 8 | */ 9 | export function applyPassive(globalObj = window, forceRefresh = false) { 10 | if (supportsPassive_ === undefined || forceRefresh) { 11 | let isSupported = false 12 | try { 13 | globalObj.document.addEventListener('test', null, { 14 | get passive() { 15 | isSupported = { passive: true } 16 | } 17 | }) 18 | } catch (e) { 19 | //empty 20 | } 21 | 22 | supportsPassive_ = isSupported 23 | } 24 | 25 | return supportsPassive_ 26 | } 27 | -------------------------------------------------------------------------------- /components/base/auto-init.js: -------------------------------------------------------------------------------- 1 | export function autoInit(plugin) { 2 | // Auto-install 3 | let _Vue = null 4 | if (typeof window !== 'undefined') { 5 | _Vue = window.Vue 6 | } else if (typeof global !== 'undefined') { 7 | /*global global*/ 8 | _Vue = global.Vue 9 | } 10 | if (_Vue) { 11 | _Vue.use(plugin) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /components/base/base-plugin.js: -------------------------------------------------------------------------------- 1 | export function BasePlugin(components) { 2 | return { 3 | version: '__VERSION__', 4 | install: vm => { 5 | for (let key in components) { 6 | let component = components[key] 7 | vm.component(component.name, component) 8 | } 9 | }, 10 | components 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /components/base/custom-button.js: -------------------------------------------------------------------------------- 1 | export const CustomButton = { 2 | name: 'custom-button', 3 | functional: true, 4 | props: { 5 | link: Object 6 | }, 7 | render(h, context) { 8 | let element 9 | let data = Object.assign({}, context.data) 10 | 11 | if (context.props.link && context.parent.$router) { 12 | // router-link case 13 | element = context.parent.$root.$options.components['router-link'] 14 | data.props = Object.assign({ tag: context.props.tag }, context.props.link) 15 | data.attrs.role = 'button' 16 | if (data.on.click) { 17 | data.nativeOn = { click: data.on.click } 18 | } 19 | } else if (data.attrs && data.attrs.href) { 20 | // href case 21 | element = 'a' 22 | data.attrs.role = 'button' 23 | } else { 24 | // button fallback 25 | element = 'button' 26 | } 27 | 28 | return h(element, data, context.children) 29 | } 30 | } 31 | 32 | export const CustomButtonMixin = { 33 | props: { 34 | href: String, 35 | disabled: Boolean, 36 | to: [String, Object], 37 | exact: Boolean, 38 | append: Boolean, 39 | replace: Boolean, 40 | activeClass: String, 41 | exactActiveClass: String 42 | }, 43 | computed: { 44 | link() { 45 | return ( 46 | this.to && { 47 | to: this.to, 48 | exact: this.exact, 49 | append: this.append, 50 | replace: this.replace, 51 | activeClass: this.activeClass, 52 | exactActiveClass: this.exactActiveClass 53 | } 54 | ) 55 | } 56 | }, 57 | components: { 58 | CustomButton 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /components/base/custom-element.js: -------------------------------------------------------------------------------- 1 | export const CustomElement = { 2 | functional: true, 3 | render(createElement, context) { 4 | return createElement( 5 | context.props.is || context.props.tag || 'div', 6 | context.data, 7 | context.children 8 | ) 9 | } 10 | } 11 | 12 | export const CustomElementMixin = { 13 | components: { 14 | CustomElement 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /components/base/custom-event.js: -------------------------------------------------------------------------------- 1 | /* global CustomEvent */ 2 | 3 | export function emitCustomEvent(el, evtType, evtData, shouldBubble = false) { 4 | let evt 5 | if (typeof CustomEvent === 'function') { 6 | evt = new CustomEvent(evtType, { 7 | detail: evtData, 8 | bubbles: shouldBubble 9 | }) 10 | } else { 11 | evt = document.createEvent('CustomEvent') 12 | evt.initCustomEvent(evtType, shouldBubble, false, evtData) 13 | } 14 | el.dispatchEvent(evt) 15 | } 16 | -------------------------------------------------------------------------------- /components/base/custom-icon.js: -------------------------------------------------------------------------------- 1 | export function extractIconProp(iconProp) { 2 | if (typeof iconProp === 'string') { 3 | return { 4 | classes: { 'material-icons': true }, 5 | content: iconProp 6 | } 7 | } else if (iconProp instanceof Array) { 8 | return { 9 | classes: iconProp.reduce( 10 | (result, value) => Object.assign(result, { [value]: true }), 11 | {} 12 | ) 13 | } 14 | } else if (typeof iconProp === 'object') { 15 | return { 16 | classes: iconProp.className 17 | .split(' ') 18 | .reduce( 19 | (result, value) => Object.assign(result, { [value]: true }), 20 | {} 21 | ), 22 | content: iconProp.textContent 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /components/base/custom-link.js: -------------------------------------------------------------------------------- 1 | export const CustomLink = { 2 | name: 'custom-link', 3 | functional: true, 4 | props: { 5 | tag: { type: String, default: 'a' }, 6 | link: Object 7 | }, 8 | render(h, context) { 9 | let element 10 | let data = Object.assign({}, context.data) 11 | 12 | if (context.props.link && context.parent.$router) { 13 | // router-link case 14 | element = context.parent.$root.$options.components['router-link'] 15 | data.props = Object.assign({ tag: context.props.tag }, context.props.link) 16 | if (data.on.click) { 17 | data.nativeOn = { click: data.on.click } 18 | } 19 | } else { 20 | // element fallback 21 | element = context.props.tag 22 | } 23 | 24 | return h(element, data, context.children) 25 | } 26 | } 27 | 28 | export const CustomLinkMixin = { 29 | props: { 30 | to: [String, Object], 31 | exact: Boolean, 32 | append: Boolean, 33 | replace: Boolean, 34 | activeClass: String, 35 | exactActiveClass: String 36 | }, 37 | computed: { 38 | link() { 39 | return ( 40 | this.to && { 41 | to: this.to, 42 | exact: this.exact, 43 | append: this.append, 44 | replace: this.replace, 45 | activeClass: this.activeClass, 46 | exactActiveClass: this.exactActiveClass 47 | } 48 | ) 49 | } 50 | }, 51 | components: { 52 | CustomLink 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /components/base/dispatch-event-mixin.js: -------------------------------------------------------------------------------- 1 | export const DispatchEventMixin = { 2 | props: { 3 | event: String, 4 | 'event-target': Object, 5 | 'event-args': Array 6 | }, 7 | methods: { 8 | dispatchEvent(evt) { 9 | evt && this.$emit(evt.type, evt) 10 | if (this.event) { 11 | let target = this.eventTarget || this.$root 12 | let args = this.eventArgs || [] 13 | target.$emit(this.event, ...args) 14 | } 15 | } 16 | }, 17 | computed: { 18 | listeners() { 19 | return { 20 | ...this.$listeners, 21 | click: e => this.dispatchEvent(e) 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /components/base/dispatch-focus-mixin.js: -------------------------------------------------------------------------------- 1 | export const DispatchFocusMixin = { 2 | data() { 3 | return { hasFocus: false } 4 | }, 5 | methods: { 6 | onMouseDown() { 7 | this._active = true 8 | }, 9 | onMouseUp() { 10 | this._active = false 11 | }, 12 | onFocusEvent() { 13 | // dispatch async to let time to other focus event to propagate 14 | setTimeout(() => this.dispatchFocusEvent(), 0) 15 | }, 16 | onBlurEvent() { 17 | // dispatch async to let time to other focus event to propagate 18 | // also filtur blur if mousedown 19 | this._active || setTimeout(() => this.dispatchFocusEvent(), 0) 20 | }, 21 | dispatchFocusEvent() { 22 | let hasFocus = 23 | this.$el === document.activeElement || 24 | this.$el.contains(document.activeElement) 25 | if (hasFocus != this.hasFocus) { 26 | this.$emit(hasFocus ? 'focus' : 'blur') 27 | this.hasFocus = hasFocus 28 | } 29 | } 30 | }, 31 | mounted() { 32 | this.$el.addEventListener('focusin', this.onFocusEvent) 33 | this.$el.addEventListener('focusout', this.onBlurEvent) 34 | this.$el.addEventListener('mousedown', this.onMouseDown) 35 | this.$el.addEventListener('mouseup', this.onMouseUp) 36 | }, 37 | beforeDestroy() { 38 | this.$el.removeEventListener('focusin', this.onFocusEvent) 39 | this.$el.removeEventListener('focusout', this.onBlurEvent) 40 | this.$el.removeEventListener('mousedown', this.onMouseDown) 41 | this.$el.removeEventListener('mouseup', this.onMouseUp) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /components/base/index.js: -------------------------------------------------------------------------------- 1 | export * from './apply-passive.js' 2 | export * from './auto-init.js' 3 | export * from './base-plugin.js' 4 | export * from './custom-element.js' 5 | export * from './custom-link.js' 6 | export * from './custom-event.js' 7 | export * from './custom-button.js' 8 | export * from './custom-icon.js' 9 | export * from './dispatch-event-mixin.js' 10 | export * from './dispatch-focus-mixin.js' 11 | export * from './uniqueid-mixin.js' 12 | -------------------------------------------------------------------------------- /components/base/uniqueid-mixin.js: -------------------------------------------------------------------------------- 1 | const scope = 2 | Math.floor(Math.random() * Math.floor(0x10000000)).toString() + '-' 3 | 4 | export const VMAUniqueIdMixin = { 5 | beforeCreate() { 6 | this.vma_uid_ = scope + this._uid 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /components/button/demo.vue: -------------------------------------------------------------------------------- 1 | 47 | 48 | 79 | 80 | 81 | 95 | -------------------------------------------------------------------------------- /components/button/entry.js: -------------------------------------------------------------------------------- 1 | import './styles.scss' 2 | import { autoInit } from '../base' 3 | import plugin from './index.js' 4 | export default plugin 5 | 6 | autoInit(plugin) 7 | -------------------------------------------------------------------------------- /components/button/index.js: -------------------------------------------------------------------------------- 1 | import { BasePlugin } from '../base' 2 | import mdcButton from './mdc-button.vue' 3 | import mdcButtonBase from './mdc-button-base.vue' 4 | 5 | export { mdcButtonBase, mdcButton } 6 | 7 | export default BasePlugin({ 8 | mdcButton 9 | }) 10 | -------------------------------------------------------------------------------- /components/button/mdc-button-base.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 29 | -------------------------------------------------------------------------------- /components/button/mdc-button.vue: -------------------------------------------------------------------------------- 1 | 40 | -------------------------------------------------------------------------------- /components/button/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/button/mdc-button"; 2 | 3 | .mdc-button { 4 | .mdc-icon { 5 | @extend .mdc-button__icon; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /components/button/test.spec.js: -------------------------------------------------------------------------------- 1 | import { pluginSanityCheck } from '../unit-test' 2 | import plugin from './index.js' 3 | 4 | pluginSanityCheck(__dirname, plugin) 5 | -------------------------------------------------------------------------------- /components/card/demo.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 33 | 34 | 41 | -------------------------------------------------------------------------------- /components/card/entry.js: -------------------------------------------------------------------------------- 1 | import './styles.scss' 2 | import { autoInit } from '../base' 3 | import plugin from './index.js' 4 | export default plugin 5 | 6 | autoInit(plugin) 7 | -------------------------------------------------------------------------------- /components/card/index.js: -------------------------------------------------------------------------------- 1 | import { BasePlugin } from '../base' 2 | import mdcCard from './mdc-card.vue' 3 | import mdcCardPrimaryAction from './mdc-card-primary-action.vue' 4 | import mdcCardMedia from './mdc-card-media.vue' 5 | import mdcCardHeader from './mdc-card-header.vue' 6 | import mdcCardTitle from './mdc-card-title.vue' 7 | import mdcCardSubtitle from './mdc-card-subtitle.vue' 8 | import mdcCardText from './mdc-card-text.vue' 9 | import mdcCardActions from './mdc-card-actions.vue' 10 | import mdcCardActionButtons from './mdc-card-action-buttons.vue' 11 | import mdcCardActionButton from './mdc-card-action-button.vue' 12 | import mdcCardActionIcons from './mdc-card-action-icons.vue' 13 | import mdcCardActionIcon from './mdc-card-action-icon.vue' 14 | 15 | export { 16 | mdcCard, 17 | mdcCardPrimaryAction, 18 | mdcCardMedia, 19 | mdcCardHeader, 20 | mdcCardTitle, 21 | mdcCardSubtitle, 22 | mdcCardText, 23 | mdcCardActions, 24 | mdcCardActionButtons, 25 | mdcCardActionButton, 26 | mdcCardActionIcons, 27 | mdcCardActionIcon 28 | } 29 | 30 | export default BasePlugin({ 31 | mdcCard, 32 | mdcCardPrimaryAction, 33 | mdcCardMedia, 34 | mdcCardHeader, 35 | mdcCardTitle, 36 | mdcCardSubtitle, 37 | mdcCardText, 38 | mdcCardActions, 39 | mdcCardActionButtons, 40 | mdcCardActionButton, 41 | mdcCardActionIcons, 42 | mdcCardActionIcon 43 | }) 44 | -------------------------------------------------------------------------------- /components/card/mdc-card-action-button.vue: -------------------------------------------------------------------------------- 1 | 18 | -------------------------------------------------------------------------------- /components/card/mdc-card-action-buttons.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /components/card/mdc-card-action-icon.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 48 | -------------------------------------------------------------------------------- /components/card/mdc-card-action-icons.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /components/card/mdc-card-actions.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 24 | -------------------------------------------------------------------------------- /components/card/mdc-card-header.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 31 | -------------------------------------------------------------------------------- /components/card/mdc-card-media.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 35 | -------------------------------------------------------------------------------- /components/card/mdc-card-primary-action.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 26 | -------------------------------------------------------------------------------- /components/card/mdc-card-subtitle.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 14 | -------------------------------------------------------------------------------- /components/card/mdc-card-text.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /components/card/mdc-card-title.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | -------------------------------------------------------------------------------- /components/card/mdc-card.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | -------------------------------------------------------------------------------- /components/card/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/button/mdc-button"; 2 | @import "@material/card/mdc-card"; 3 | 4 | .mdc-card-media { 5 | background-size: cover; 6 | background-repeat: no-repeat; 7 | } 8 | 9 | // Legacy mdc layout 10 | .mdc-card { 11 | &__title { 12 | @include mdc-typography(body2); 13 | @include mdc-theme-prop(color, text-primary-on-light); 14 | 15 | margin: -0.063rem 0; // -1sp 0 16 | } 17 | 18 | &__title--large { 19 | @include mdc-typography(headline5); 20 | 21 | margin: 0; 22 | } 23 | 24 | &__primary { 25 | padding: 16px; 26 | 27 | // Add extra space before large title. 28 | .mdc-card__title--large { 29 | padding-top: 8px; 30 | } 31 | 32 | // Add extra padding if this is the last block. 33 | &:last-child { 34 | padding-bottom: 24px; 35 | } 36 | } 37 | 38 | &__supporting-text { 39 | @include mdc-typography(body1); 40 | @include mdc-theme-prop(color, text-primary-on-light); 41 | 42 | box-sizing: border-box; 43 | padding: 8px 16px; 44 | 45 | // Remove top padding if immediately preceded by a primary block. 46 | .mdc-card__primary + & { 47 | margin-top: -8px; 48 | padding-top: 0; 49 | } 50 | 51 | // Add extra padding if this is the last block. 52 | &:last-child { 53 | padding-bottom: 24px; 54 | } 55 | } 56 | 57 | &__subtitle { 58 | @include mdc-typography(body1); 59 | @include mdc-theme-prop(color, text-primary-on-light); 60 | 61 | margin: -0.063rem 0; // -1sp 0 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /components/card/test.spec.js: -------------------------------------------------------------------------------- 1 | import { pluginSanityCheck } from '../unit-test' 2 | import plugin from './index.js' 3 | 4 | pluginSanityCheck(__dirname, plugin) 5 | -------------------------------------------------------------------------------- /components/checkbox/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## Usage 3 | 4 | ```html 5 | 6 | ``` 7 | 8 | ```javascript 9 | var vm = new Vue({ 10 | data: { 11 | label: 'This is a checkbox', 12 | checked: true 13 | } 14 | }) 15 | ``` 16 | 17 | ### Indeterminate checkbox 18 | ```html 19 | 21 | ``` 22 | 23 | ```javascript 24 | var vm = new Vue({ 25 | data: { 26 | label: 'This is a checkbox', 27 | checked: false, 28 | indeterminate: true 29 | } 30 | }) 31 | ``` 32 | 33 | ### Custom label markup 34 | 35 | ```html 36 | 37 | I agree with 38 | Terms of Serivce 39 | 40 | ``` 41 | 42 | > use `@click.stop` to prevent triggering checkbox ripple 43 | 44 | ### props 45 | 46 | | props | Type | Default | Description | 47 | |-------|------|---------|-------------| 48 | |`checked`|Boolean|| whether the checkbox is checked, bind with `v-model` | 49 | |`indeterminate`|Boolean|| whether the checkbox is in an indeterminate state bind with `.sync` modifier | | 50 | |`disabled`| Boolean|| whether the checkbox is disabled | 51 | |`label`| String|| checkbox label | 52 | |`align-end`| Boolean|| whether to align the checkbox after the label | 53 | |`value`|String| `'on'`| checkbox value | 54 | |`name`|String|| input name | 55 | 56 | 57 | ### events 58 | 59 | | event | args | Description | 60 | |-------|------|-------------| 61 | |`@focus`| - |emitted on focus gained | 62 | |`@blur`| - |emitted on focus lost | 63 | 64 | ### Reference 65 | - 66 | -------------------------------------------------------------------------------- /components/checkbox/demo.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 24 | -------------------------------------------------------------------------------- /components/checkbox/entry.js: -------------------------------------------------------------------------------- 1 | import './styles.scss' 2 | import { autoInit } from '../base' 3 | import plugin from './index.js' 4 | export default plugin 5 | 6 | autoInit(plugin) 7 | -------------------------------------------------------------------------------- /components/checkbox/index.js: -------------------------------------------------------------------------------- 1 | import { BasePlugin } from '../base' 2 | import mdcCheckbox from './mdc-checkbox.vue' 3 | 4 | export { mdcCheckbox } 5 | 6 | export default BasePlugin({ 7 | mdcCheckbox 8 | }) 9 | -------------------------------------------------------------------------------- /components/checkbox/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/form-field/mdc-form-field"; 2 | @import "@material/checkbox/mdc-checkbox"; 3 | -------------------------------------------------------------------------------- /components/checkbox/test.spec.js: -------------------------------------------------------------------------------- 1 | import { pluginSanityCheck } from '../unit-test' 2 | import plugin from './index.js' 3 | 4 | pluginSanityCheck(__dirname, plugin) 5 | -------------------------------------------------------------------------------- /components/chips/entry.js: -------------------------------------------------------------------------------- 1 | import './styles.scss' 2 | import { autoInit } from '../base' 3 | import plugin from './index.js' 4 | export default plugin 5 | 6 | autoInit(plugin) 7 | -------------------------------------------------------------------------------- /components/chips/index.js: -------------------------------------------------------------------------------- 1 | import { BasePlugin } from '../base' 2 | import mdcChip from './mdc-chip.vue' 3 | import mdcChipSet from './mdc-chip-set.vue' 4 | 5 | export { mdcChip, mdcChipSet } 6 | 7 | export default BasePlugin({ 8 | mdcChip, 9 | mdcChipSet 10 | }) 11 | -------------------------------------------------------------------------------- /components/chips/mdc-chip-set.vue: -------------------------------------------------------------------------------- 1 | 2 | 65 | -------------------------------------------------------------------------------- /components/chips/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/chips/mdc-chips"; 2 | 3 | .mdc-chip { 4 | @include mdc-chip-selected-ink-color(#6200ee); 5 | } 6 | -------------------------------------------------------------------------------- /components/chips/test.spec.js: -------------------------------------------------------------------------------- 1 | import { mount, createLocalVue, checkValidMdcAdapter } from '../unit-test' 2 | import plugin from './index.js' 3 | import Spec from './test.spec.vue' 4 | import { mdcChip, mdcChipSet } from './index.js' 5 | 6 | describe(__dirname, () => { 7 | const localVue = createLocalVue() 8 | localVue.use(plugin) 9 | const spec = mount(Spec, { localVue }) 10 | 11 | describe('mdcChipSet', () => { 12 | const wrapper = spec.find(mdcChipSet) 13 | checkValidMdcAdapter(wrapper.vm) 14 | }) 15 | 16 | describe('mdcChip', () => { 17 | const wrapper = spec.find(mdcChip) 18 | checkValidMdcAdapter(wrapper.vm) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /components/chips/test.spec.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /components/dialog/demo.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 33 | -------------------------------------------------------------------------------- /components/dialog/entry.js: -------------------------------------------------------------------------------- 1 | import './styles.scss' 2 | import { autoInit } from '../base' 3 | import plugin from './index.js' 4 | export default plugin 5 | 6 | autoInit(plugin) 7 | -------------------------------------------------------------------------------- /components/dialog/index.js: -------------------------------------------------------------------------------- 1 | import { BasePlugin } from '../base' 2 | import mdcDialog from './mdc-dialog.vue' 3 | 4 | export { mdcDialog } 5 | 6 | export default BasePlugin({ 7 | mdcDialog 8 | }) 9 | -------------------------------------------------------------------------------- /components/dialog/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/dialog/mdc-dialog"; 2 | 3 | // TODO: MDCFIX 4 | .mdc-dialog.mdc-dialog--open { 5 | z-index: 5; 6 | } 7 | 8 | .mdc-dialog--open:not(.mdc-dialog--animating) .mdc-dialog__surface { 9 | transform: none !important; 10 | } 11 | -------------------------------------------------------------------------------- /components/dialog/test.spec.js: -------------------------------------------------------------------------------- 1 | import { pluginSanityCheck } from '../unit-test' 2 | import plugin from './index.js' 3 | 4 | pluginSanityCheck(__dirname, plugin, { 5 | mdcDialog: { 6 | propsData: { 7 | title: 'title' 8 | } 9 | } 10 | }) 11 | -------------------------------------------------------------------------------- /components/drawer/demo.vue: -------------------------------------------------------------------------------- 1 |