├── .circleci └── config.yml ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── .npmignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── babel.config.js ├── components ├── README.md ├── auto-init │ ├── AutoInit.vue │ ├── README.md │ └── index.js ├── base │ ├── baseComponentMixin.js │ ├── index.js │ └── themeClassMixin.js ├── button │ ├── Button.vue │ ├── README.md │ ├── __tests__ │ │ ├── Button.spec.js │ │ └── __snapshots__ │ │ │ └── Button.spec.js.snap │ ├── index.js │ └── styles.scss ├── card │ ├── Card.vue │ ├── CardMedia.vue │ ├── CardPrimaryAction.vue │ ├── README.md │ ├── __test__ │ │ ├── Card.spec.js │ │ └── __snapshots__ │ │ │ └── Card.spec.js.snap │ ├── index.js │ └── styles.scss ├── checkbox │ ├── Checkbox.vue │ ├── README.md │ ├── __test__ │ │ ├── Checkbox.spec.js │ │ └── __snapshots__ │ │ │ └── Checkbox.spec.js.snap │ ├── index.js │ └── styles.scss ├── chips │ ├── Chip.vue │ ├── ChipSet.vue │ ├── README.md │ ├── index.js │ └── styles.scss ├── dialog │ ├── Dialog.vue │ ├── README.md │ ├── __test__ │ │ ├── Dialog.spec.js │ │ └── __snapshots__ │ │ │ └── Dialog.spec.js.snap │ ├── index.js │ └── styles.scss ├── drawer │ ├── Drawer.vue │ ├── DrawerAppContent.vue │ ├── DrawerContent.vue │ ├── DrawerHeader.vue │ ├── DrawerList.vue │ ├── DrawerScrim.vue │ ├── README.md │ ├── __test__ │ │ ├── Drawer.spec.js │ │ └── __snapshots__ │ │ │ └── Drawer.spec.js.snap │ ├── index.js │ └── styles.scss ├── elevation │ ├── Elevation.vue │ ├── README.md │ ├── index.js │ └── styles.scss ├── fab │ ├── Fab.vue │ ├── README.md │ ├── __test__ │ │ ├── Fab.spec.js │ │ └── __snapshots__ │ │ │ └── Fab.spec.js.snap │ ├── index.js │ └── styles.scss ├── floating-label │ ├── FloatingLabel.vue │ ├── README.md │ ├── __test__ │ │ ├── FloatingLabel.spec.js │ │ └── __snapshots__ │ │ │ └── FloatingLabel.spec.js.snap │ ├── index.js │ └── styles.scss ├── form-field │ ├── FormField.vue │ ├── README.md │ ├── index.js │ └── styles.scss ├── grid-list │ ├── GridList.vue │ ├── GridListTile.vue │ ├── README.md │ ├── index.js │ └── styles.scss ├── icon-button │ ├── IconButton.vue │ ├── README.md │ ├── __tests__ │ │ ├── IconButton.spec.js │ │ └── __snapshots__ │ │ │ └── IconButton.spec.js.snap │ ├── index.js │ └── styles.scss ├── icon │ ├── Icon.vue │ ├── README.md │ └── index.js ├── image-list │ ├── ImageList.vue │ ├── ImageListItem.vue │ ├── README.md │ ├── __tests__ │ │ ├── ImageList.spec.js │ │ └── __snapshots__ │ │ │ └── ImageList.spec.js.snap │ ├── index.js │ └── styles.scss ├── index.js ├── initPlugin.js ├── layout-grid │ ├── LayoutGrid.vue │ ├── LayoutGridCell.vue │ ├── LayoutGridInner.vue │ ├── README.md │ ├── index.js │ └── styles.scss ├── line-ripple │ ├── LineRipple.vue │ ├── README.md │ ├── index.js │ └── styles.scss ├── linear-progress │ ├── LinearProgress.vue │ ├── README.md │ ├── __test__ │ │ ├── LinearProgress.spec.js │ │ └── __snapshots__ │ │ │ └── LinearProgress.spec.js.snap │ ├── index.js │ └── styles.scss ├── list │ ├── List.vue │ ├── ListDivider.vue │ ├── ListGroup.vue │ ├── ListGroupDivider.vue │ ├── ListGroupSubheader.vue │ ├── ListItem.vue │ ├── README.md │ ├── __test__ │ │ ├── List.spec.js │ │ └── __snapshots__ │ │ │ └── List.spec.js.snap │ ├── index.js │ └── styles.scss ├── menu │ ├── Menu.vue │ ├── MenuAnchor.vue │ ├── MenuSelectionGroup.vue │ ├── MenuSurface.vue │ ├── README.md │ ├── __test__ │ │ ├── Menu.spec.js │ │ └── __snapshots__ │ │ │ └── Menu.spec.js.snap │ ├── index.js │ └── styles.scss ├── notched-outline │ ├── NotchedOutline.vue │ ├── README.md │ ├── index.js │ └── styles.scss ├── radio │ ├── README.md │ ├── Radio.vue │ ├── __test__ │ │ ├── Radio.spec.js │ │ └── __snapshots__ │ │ │ └── Radio.spec.js.snap │ ├── index.js │ └── styles.scss ├── ripple │ ├── README.md │ ├── Ripple.vue │ ├── index.js │ └── styles.scss ├── select │ ├── README.md │ ├── Select.vue │ ├── SelectHelperText.vue │ ├── SelectIcon.vue │ ├── index.js │ └── styles.scss ├── shape │ ├── README.md │ ├── Shape.vue │ ├── index.js │ └── styles.scss ├── slider │ ├── README.md │ ├── Slider.vue │ ├── __tests__ │ │ ├── Slider.spec.js │ │ └── __snapshots__ │ │ │ └── Slider.spec.js.snap │ ├── index.js │ └── styles.scss ├── snackbar │ ├── README.md │ ├── Snackbar.vue │ ├── __tests__ │ │ ├── Snackbar.spec.js │ │ └── __snapshots__ │ │ │ └── Snackbar.spec.js.snap │ ├── index.js │ └── styles.scss ├── switch │ ├── README.md │ ├── Switch.vue │ ├── __test__ │ │ ├── Switch.spec.js │ │ └── __snapshots__ │ │ │ └── Switch.spec.js.snap │ ├── index.js │ └── styles.scss ├── tabs │ ├── README.md │ ├── Tab.vue │ ├── TabBar.vue │ ├── TabIndicator.vue │ ├── TabScroller.vue │ ├── index.js │ └── styles.scss ├── text-field │ ├── README.md │ ├── TextField.vue │ ├── TextFieldCharacterCounter.vue │ ├── TextFieldHelperLine.vue │ ├── TextFieldHelperText.vue │ ├── TextFieldIcon.vue │ ├── __test__ │ │ ├── TextField.spec.js │ │ └── __snapshots__ │ │ │ └── TextField.spec.js.snap │ ├── index.js │ └── styles.scss ├── theme │ ├── README.md │ ├── Theme.vue │ ├── index.js │ └── styles.scss ├── top-app-bar │ ├── README.md │ ├── TopAppBar.vue │ ├── TopAppBarFixedAdjust.vue │ ├── __tests__ │ │ ├── TopAppBar.spec.js │ │ └── __snapshots__ │ │ │ └── TopAppBar.spec.js.snap │ ├── index.js │ └── styles.scss └── typography │ ├── Body.vue │ ├── Button.vue │ ├── Caption.vue │ ├── Headline.vue │ ├── Overline.vue │ ├── README.md │ ├── Subheading.vue │ ├── Typography.vue │ ├── index.js │ └── styles.scss ├── docs ├── .vuepress │ ├── components │ │ ├── ButtonDemo.vue │ │ ├── CardDemo.vue │ │ ├── CardMediaDemo.vue │ │ ├── CheckboxDemo.vue │ │ ├── ChipsDemo.vue │ │ ├── ChipsInputDemo.vue │ │ ├── ComponentLayout.vue │ │ ├── ComponentProps.vue │ │ ├── ComponentSection.vue │ │ ├── DataTableDemo.vue │ │ ├── DialogDemo.vue │ │ ├── DismissibleDrawerDemo.vue │ │ ├── ElevationDemo.vue │ │ ├── FabDemo.vue │ │ ├── IconButtonDemo.vue │ │ ├── ImageListDemo.vue │ │ ├── LayoutGridDemo.vue │ │ ├── LinearProgressDemo.vue │ │ ├── ListWithActivatedItemDemo.vue │ │ ├── ListWithTrailingCheckboxDemo.vue │ │ ├── ListWithTrailingRadioButtonsDemo.vue │ │ ├── MenuDemo.vue │ │ ├── MenuSurfaceDemo.vue │ │ ├── ModalDrawerDemo.vue │ │ ├── PermanentDrawerDemo.vue │ │ ├── RippleDemo.vue │ │ ├── SelectDemo.vue │ │ ├── SingleLineListDemo.vue │ │ ├── SliderDemo.vue │ │ ├── SnackbarDemo.vue │ │ ├── SwitchDemo.vue │ │ ├── TabsDemo.vue │ │ ├── TextfieldDemo.vue │ │ ├── TopAppBarDemo.vue │ │ ├── TwoLineListDemo.vue │ │ ├── TwoLineWithLeadingAndTrailingIconAndDividerDemo.vue │ │ ├── drawer │ │ │ ├── DismissibleDrawerDemo.vue │ │ │ ├── ModalDrawerDemo.vue │ │ │ └── PermanentDrawerDemo.vue │ │ ├── ripple │ │ │ └── MyButton.vue │ │ └── topAppBar │ │ │ └── Demo.vue │ ├── config.js │ ├── enhanceApp.js │ ├── override.styl │ ├── public │ │ ├── assets │ │ │ ├── fonts │ │ │ │ ├── materialicons-regular.woff │ │ │ │ ├── materialicons-regular.woff2 │ │ │ │ ├── roboto-300.woff │ │ │ │ ├── roboto-300.woff2 │ │ │ │ ├── roboto-500.woff │ │ │ │ ├── roboto-500.woff2 │ │ │ │ ├── roboto-regular.woff │ │ │ │ └── roboto-regular.woff2 │ │ │ ├── icons │ │ │ │ └── material-components-vue.svg │ │ │ └── images │ │ │ │ ├── cat.jpg │ │ │ │ ├── cat_169.jpg │ │ │ │ └── mcv-hero.png │ │ └── logo.png │ └── styles.scss ├── README.md ├── components │ ├── README.md │ ├── dismissibleDrawer.md │ ├── modalDrawer.md │ ├── permanentDrawer.md │ └── top-app-bar.md └── guide │ └── README.md ├── package-lock.json ├── package.json ├── renovate.json ├── webpack.config.common.js ├── webpack.config.js └── webpack.config.min.js /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | docker: 5 | - image: circleci/node:lts 6 | steps: 7 | - checkout 8 | - run: npm ci 9 | - run: npm run build:min 10 | test: 11 | docker: 12 | - image: circleci/node:lts 13 | steps: 14 | - checkout 15 | - run: npm ci 16 | - run: npm run test 17 | docs: 18 | docker: 19 | - image: circleci/node:lts 20 | steps: 21 | - checkout 22 | - run: npm ci 23 | - run: npm run docs:prod 24 | - persist_to_workspace: 25 | root: docs/.vuepress/ 26 | paths: dist 27 | docs_deploy: 28 | docker: 29 | - image: circleci/node:lts 30 | steps: 31 | - checkout 32 | - attach_workspace: 33 | at: docs/.vuepress 34 | - add_ssh_keys: 35 | fingerprints: 36 | - "65:d8:ed:b9:bd:96:10:d0:99:95:06:d7:ae:73:7c:58" 37 | - run: 38 | name: Install and configure dependencies 39 | command: | 40 | npm install -D gh-pages 41 | git config user.email "ci-build@circleci.com" 42 | git config user.name "ci-build" 43 | - run: ./node_modules/.bin/gh-pages --dist docs/.vuepress/dist 44 | workflows: 45 | version: 2 46 | test_build_docs: 47 | jobs: 48 | - test 49 | - build 50 | - docs 51 | - docs_deploy: 52 | requires: 53 | - test 54 | - build 55 | - docs 56 | filters: 57 | branches: 58 | only: master -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior: 12 | 1. Go to '...' 13 | 2. Click on '....' 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | **Expected behavior** 18 | A clear and concise description of what you expected to happen. 19 | 20 | **Screenshots** 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | **Desktop (please complete the following information):** 24 | - OS: [e.g. iOS] 25 | - Browser [e.g. chrome, safari] 26 | - Version [e.g. 22] 27 | 28 | **Smartphone (please complete the following information):** 29 | - Device: [e.g. iPhone6] 30 | - OS: [e.g. iOS8.1] 31 | - Browser [e.g. stock browser, safari] 32 | - Version [e.g. 22] 33 | 34 | **Additional context** 35 | Add any other context about the problem here. 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .vscode/ 3 | yarn-error.log 4 | yarn.lock 5 | reports/ 6 | dist/ 7 | .idea/ 8 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test/ 2 | node_modules 3 | .vscode 4 | .github 5 | .travis.yml 6 | **/coverage 7 | .circleci/ 8 | renovate.json 9 | docs -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to material-components-vue 2 | 3 | ## Commit guideline 4 | 5 | This project use the `standard-version` package to version the NPM package and generate automatically a changelog. Because of this all commits to master should follow the [Conventional Commits Specification](https://conventionalcommits.org/). 6 | 7 | ## Contribution workflow 8 | 9 | The changes should be developed in your own fork and based on branches. 10 | When you have finished your work you create a PR (pull request) on Github. 11 | PRs should be squashed to one commit on master - following the commit [guideline](#commit-guideline). 12 | 13 | ## Component development 14 | 15 | All components should be placed in the `components` directory. Every component has a `README` in it's root directory that documentate the component. Component tests should placed in the `__tests__` directory in each component. Additionally each component should have a demo in `docs/.vuepress/components` and registered in `docs/.vuepress/README.md`. 16 | 17 | ## Upgrading mdc-web 18 | 19 | Please be sure that you switch to the right versioned tag when you want to upgrade to a specific version of mdc-web. 20 | 21 | ## Setup project 22 | 23 | Fork the project on Github and clone your own repository to your machine. 24 | This project uses yarn as default packagemanager - so be sure to install yarn first. After that install all dependencies with: 25 | 26 | ```shell 27 | $ yarn 28 | ``` 29 | 30 | ### Build all components (dev) 31 | ```shell 32 | $ yarn build 33 | ``` 34 | 35 | ### Build all components (dev) in watch-mode 36 | ```shell 37 | $ yarn watch:dev 38 | ``` 39 | 40 | ### Build all components (prod) 41 | ```shell 42 | $ yarn build:min 43 | ``` 44 | 45 | ### Serve docs (dev) 46 | ```shell 47 | $ yarn docs:dev 48 | ``` 49 | 50 | ### Build docs (prod) 51 | ```shell 52 | $ yarn docs:prod 53 | ``` 54 | 55 | ### Run tests 56 | ```shell 57 | $ yarn test 58 | ``` 59 | 60 | ### Run tests in watch-mode 61 | ```shell 62 | $ yarn test:watch 63 | ``` 64 | 65 | ### Run tests and update snapshots 66 | ```shell 67 | $ yarn test:updateSnapshot 68 | ``` 69 | 70 | ### Lint all files (js/vue) 71 | ```shell 72 | $ yarn lint 73 | ``` 74 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Mats Pfeiffer 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function (api) { 2 | const plugins = [] 3 | const presets = [] 4 | 5 | switch (api.env()) { 6 | case 'testing': 7 | presets.push([ 8 | '@babel/preset-env', 9 | { 10 | targets: { 11 | node: 'current' 12 | } 13 | } 14 | ]) 15 | break 16 | case 'development': 17 | plugins.push( 18 | '@babel/plugin-proposal-object-rest-spread', 19 | '@babel/plugin-transform-object-assign' 20 | ) 21 | presets.push([ 22 | '@babel/preset-env', 23 | { 24 | modules: false 25 | } 26 | ]) 27 | break 28 | case 'production': 29 | plugins.push( 30 | '@babel/plugin-proposal-object-rest-spread', 31 | '@babel/plugin-transform-object-assign' 32 | ) 33 | presets.push([ 34 | '@babel/preset-env', 35 | { 36 | modules: false 37 | } 38 | ]) 39 | } 40 | 41 | return { plugins, presets } 42 | } 43 | -------------------------------------------------------------------------------- /components/README.md: -------------------------------------------------------------------------------- 1 | This directory contains all of the individual components. Each component can be used as standalone vue plugin. -------------------------------------------------------------------------------- /components/auto-init/README.md: -------------------------------------------------------------------------------- 1 | ## Auto Init 2 | 3 | ### Markup 4 | 5 | ```html 6 | 7 | 13 | 14 | ``` 15 | 16 | ### Script 17 | 18 | ```javascript 19 | data () { 20 | return { 21 | textField: undefined // after initialization, it will be an MDCTextField instance 22 | } 23 | } 24 | ``` 25 | 26 | ### Re-Initialize 27 | 28 | ```javascript 29 | this.$refs.component.destroy() 30 | this.$refs.component.$el.removeAttribute('data-mdc-auto-init-state') 31 | ``` 32 | 33 | ### Events 34 | 35 | | Event | Payload | Description | 36 | |-------|---------|-------------| 37 | | end | `MDCComponent` | emitted when the component being initialized | 38 | 39 | ### Methods 40 | 41 | | Method | Description | 42 | |-------|-------------| 43 | | destroy | calling `MDCComponent.destroy`, useful in re-initialization | 44 | 45 | ### Slots 46 | 47 | | Slot | Description | 48 | |------|-------------| 49 | | default | a material component dom. **Can only contain one element** | 50 | 51 | 52 | ### Reference 53 | 54 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-auto-init 55 | -------------------------------------------------------------------------------- /components/auto-init/index.js: -------------------------------------------------------------------------------- 1 | import AutoInit from './AutoInit.vue' 2 | 3 | import { initPlugin } from '../' 4 | 5 | const plugin = { 6 | install (vm) { 7 | vm.component('m-auto-init', AutoInit) 8 | } 9 | } 10 | export default plugin 11 | 12 | initPlugin(plugin) 13 | -------------------------------------------------------------------------------- /components/base/baseComponentMixin.js: -------------------------------------------------------------------------------- 1 | export const baseComponentMixin = { 2 | inheritAttrs: false 3 | } 4 | -------------------------------------------------------------------------------- /components/base/index.js: -------------------------------------------------------------------------------- 1 | export * from './baseComponentMixin.js' 2 | export * from './themeClassMixin.js' 3 | -------------------------------------------------------------------------------- /components/base/themeClassMixin.js: -------------------------------------------------------------------------------- 1 | const themeProps = [ 2 | 'primary', 3 | 'secondary', 4 | 'background', 5 | 'surface', 6 | 'on-primary', 7 | 'on-secondary', 8 | 'on-surface', 9 | 'primary-bg', 10 | 'secondary-bg', 11 | 'text-primary-on-light', 12 | 'text-secondary-on-light', 13 | 'text-hint-on-light', 14 | 'text-disabled-on-light', 15 | 'text-icon-on-light', 16 | 'text-primary-on-dark', 17 | 'text-secondary-on-dark', 18 | 'text-hint-on-dark', 19 | 'text-disabled-on-dark', 20 | 'text-icon-on-dark' 21 | ] 22 | 23 | export const themeClassMixin = { 24 | props: { 25 | theming: { 26 | type: String, 27 | default: '' 28 | } 29 | }, 30 | mounted () { 31 | if (themeProps.indexOf(this.theming) > -1) { 32 | this.$el.classList.add('mdc-theme--' + this.theming) 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /components/button/README.md: -------------------------------------------------------------------------------- 1 | ## Button 2 | 3 | ### Markup 4 | 5 | ```html 6 | 9 | Button 10 | 11 | 12 | 13 | 16 | Button 17 | 18 | 19 | Button 20 | Github 21 | 22 | 23 | 24 | ... 25 | 26 | 27 | ``` 28 | ### Props 29 | 30 | | Prop | Type | Default | Description | 31 | |------|------|---------|-------------| 32 | | raised | Boolean | false | raised button | 33 | | unelevated | Boolean | false | unelevated button | 34 | | outlined | Boolean | false | outlined button | 35 | | dense | Boolean | false | dense button | 36 | | href | String | '' | link button | 37 | | ripple | Boolean | true | use js ripple or not | 38 | 39 | Non prop attributes and events are mapped to the inner button element. 40 | 41 | ### Slots 42 | 43 | | Slot | Description | 44 | |------|-------------| 45 | | default | button label | 46 | | icon | leading icon component | 47 | | trailingIcon | trailing icon component | 48 | 49 | ### Reference 50 | 51 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-button 52 | -------------------------------------------------------------------------------- /components/button/__tests__/Button.spec.js: -------------------------------------------------------------------------------- 1 | import 'mutationobserver-shim' 2 | import { mount } from '@vue/test-utils' 3 | import Button from '../Button.vue' 4 | 5 | describe('Button', () => { 6 | it('should mount', () => { 7 | const wrapper = mount(Button) 8 | expect(wrapper.isVueInstance()).toBeTruthy() 9 | expect(wrapper.vm.$data.mdcRipple).toBeDefined() 10 | expect(wrapper.vm.$data.slotObserver).toBeDefined() 11 | }) 12 | 13 | it('should render with no prop', () => { 14 | const wrapper = mount(Button) 15 | expect(wrapper).toMatchSnapshot() 16 | expect(wrapper.classes()).toContain('mdc-button') 17 | }) 18 | 19 | it('should render as raised', () => { 20 | const wrapper = mount(Button, { 21 | propsData: { 22 | raised: true 23 | } 24 | }) 25 | expect(wrapper).toMatchSnapshot() 26 | expect(wrapper.classes()).toContain('mdc-button--raised') 27 | }) 28 | 29 | it('should render as unelevated', () => { 30 | const wrapper = mount(Button, { 31 | propsData: { 32 | unelevated: true 33 | } 34 | }) 35 | expect(wrapper).toMatchSnapshot() 36 | expect(wrapper.classes()).toContain('mdc-button--unelevated') 37 | }) 38 | 39 | it('should render as outlined', () => { 40 | const wrapper = mount(Button, { 41 | propsData: { 42 | outlined: true 43 | } 44 | }) 45 | expect(wrapper).toMatchSnapshot() 46 | expect(wrapper.classes()).toContain('mdc-button--outlined') 47 | }) 48 | 49 | it('should render as dense', () => { 50 | const wrapper = mount(Button, { 51 | propsData: { 52 | dense: true 53 | } 54 | }) 55 | expect(wrapper).toMatchSnapshot() 56 | expect(wrapper.classes()).toContain('mdc-button--dense') 57 | }) 58 | 59 | it('should render without ripple', () => { 60 | const wrapper = mount(Button, { 61 | propsData: { 62 | ripple: false 63 | } 64 | }) 65 | expect(wrapper).toMatchSnapshot() 66 | expect(wrapper.vm.$data.mdcRipple).toBeUndefined() 67 | }) 68 | }) 69 | -------------------------------------------------------------------------------- /components/button/__tests__/__snapshots__/Button.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Button should render as dense 1`] = ``; 4 | 5 | exports[`Button should render as outlined 1`] = ``; 6 | 7 | exports[`Button should render as raised 1`] = ``; 8 | 9 | exports[`Button should render as unelevated 1`] = ``; 10 | 11 | exports[`Button should render with no prop 1`] = ``; 12 | 13 | exports[`Button should render without ripple 1`] = ``; 14 | -------------------------------------------------------------------------------- /components/button/index.js: -------------------------------------------------------------------------------- 1 | import Button from './Button.vue' 2 | import './styles.scss' 3 | 4 | import { initPlugin } from '../' 5 | 6 | const plugin = { 7 | install (vm) { 8 | vm.component('m-button', Button) 9 | } 10 | } 11 | export default plugin 12 | 13 | initPlugin(plugin) 14 | -------------------------------------------------------------------------------- /components/button/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/button/mdc-button"; 2 | -------------------------------------------------------------------------------- /components/card/CardMedia.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 40 | -------------------------------------------------------------------------------- /components/card/CardPrimaryAction.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 51 | -------------------------------------------------------------------------------- /components/card/index.js: -------------------------------------------------------------------------------- 1 | import Card from './Card.vue' 2 | import CardMedia from './CardMedia.vue' 3 | import CardPrimaryAction from './CardPrimaryAction' 4 | import './styles.scss' 5 | 6 | import { initPlugin } from '../' 7 | 8 | const plugin = { 9 | install (vm) { 10 | vm.component('m-card', Card) 11 | vm.component('m-card-media', CardMedia) 12 | vm.component('m-card-primary-action', CardPrimaryAction) 13 | } 14 | } 15 | export default plugin 16 | 17 | initPlugin(plugin) 18 | -------------------------------------------------------------------------------- /components/card/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/card/mdc-card"; 2 | -------------------------------------------------------------------------------- /components/checkbox/Checkbox.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 101 | -------------------------------------------------------------------------------- /components/checkbox/README.md: -------------------------------------------------------------------------------- 1 | ## Checkbox 2 | 3 | ### Markup 4 | 5 | ```html 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | ``` 15 | 16 | ### Props 17 | 18 | | Prop | Type | Default | Description | 19 | |------|------|---------|-------------| 20 | | checked | Boolean | false | checkbox value | 21 | | indeterminate | Boolean | false | not true not false | 22 | 23 | Non prop attributes are mapped to the inner input element. 24 | 25 | ### Reference 26 | 27 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-checkbox 28 | -------------------------------------------------------------------------------- /components/checkbox/__test__/Checkbox.spec.js: -------------------------------------------------------------------------------- 1 | import 'mutationobserver-shim' 2 | import { mount } from '@vue/test-utils' 3 | import Checkbox from '../Checkbox.vue' 4 | 5 | describe('Checkbox', () => { 6 | it('should mount', () => { 7 | const wrapper = mount(Checkbox) 8 | expect(wrapper.isVueInstance()).toBeTruthy() 9 | expect(wrapper.vm.$data.mdcCheckbox).toBeDefined() 10 | }) 11 | 12 | it('should render with no prop', () => { 13 | const wrapper = mount(Checkbox) 14 | expect(wrapper).toMatchSnapshot() 15 | expect(wrapper.classes()).toContain('mdc-checkbox') 16 | expect(wrapper.find('input').attributes('disabled')).toBeUndefined() 17 | }) 18 | 19 | it('should render as disabled', () => { 20 | const wrapper = mount(Checkbox, { 21 | propsData: { 22 | disabled: true 23 | } 24 | }) 25 | expect(wrapper).toMatchSnapshot() 26 | expect(wrapper.classes()).toContain('mdc-checkbox--disabled') 27 | expect(wrapper.find('input').attributes('disabled')).toBeDefined() 28 | }) 29 | 30 | it('should render as indeterminate', () => { 31 | const wrapper = mount(Checkbox, { 32 | propsData: { 33 | indeterminate: true 34 | } 35 | }) 36 | expect(wrapper).toMatchSnapshot() 37 | expect(wrapper.vm.$data.mdcCheckbox.indeterminate).toBeTruthy() 38 | expect(wrapper.find('input').element.checked).toBeFalsy() 39 | expect(wrapper.find('input').element.indeterminate).toBeTruthy() 40 | }) 41 | 42 | it('should render as checked', () => { 43 | const wrapper = mount(Checkbox, { 44 | propsData: { 45 | checked: true 46 | } 47 | }) 48 | expect(wrapper).toMatchSnapshot() 49 | expect(wrapper.vm.$data.mdcCheckbox.checked).toBeTruthy() 50 | expect(wrapper.find('input').element.checked).toBeTruthy() 51 | }) 52 | 53 | it('should render and emit', () => { 54 | const wrapper = mount(Checkbox) 55 | 56 | const input = wrapper.find('input') 57 | 58 | input.setChecked() 59 | expect(wrapper.emitted().change).toBeTruthy() 60 | expect(wrapper.emitted().change.length).toBe(1) 61 | expect(wrapper.emitted().change[0]).toEqual([true]) 62 | expect(wrapper.vm.$data.mdcCheckbox.checked).toBeTruthy() 63 | expect(wrapper.find('input').element.checked).toBeTruthy() 64 | 65 | input.setChecked(false) 66 | expect(wrapper.emitted().change).toBeTruthy() 67 | expect(wrapper.emitted().change.length).toBe(2) 68 | expect(wrapper.emitted().change[1]).toEqual([false]) 69 | expect(wrapper.vm.$data.mdcCheckbox.checked).toBeFalsy() 70 | expect(wrapper.find('input').element.checked).toBeFalsy() 71 | }) 72 | }) 73 | -------------------------------------------------------------------------------- /components/checkbox/__test__/__snapshots__/Checkbox.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Checkbox should render as checked 1`] = ` 4 |
5 |
6 | 7 | 8 |
9 |
10 |
11 | `; 12 | 13 | exports[`Checkbox should render as disabled 1`] = ` 14 |
15 |
16 | 17 | 18 |
19 |
20 |
21 | `; 22 | 23 | exports[`Checkbox should render as indeterminate 1`] = ` 24 |
25 |
26 | 27 | 28 |
29 |
30 |
31 | `; 32 | 33 | exports[`Checkbox should render with no prop 1`] = ` 34 |
35 |
36 | 37 | 38 |
39 |
40 |
41 | `; 42 | -------------------------------------------------------------------------------- /components/checkbox/index.js: -------------------------------------------------------------------------------- 1 | import Checkbox from './Checkbox.vue' 2 | import './styles.scss' 3 | 4 | import { initPlugin } from '../' 5 | 6 | const plugin = { 7 | install (vm) { 8 | vm.component('m-checkbox', Checkbox) 9 | } 10 | } 11 | export default plugin 12 | 13 | initPlugin(plugin) 14 | -------------------------------------------------------------------------------- /components/checkbox/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/checkbox/mdc-checkbox"; -------------------------------------------------------------------------------- /components/chips/index.js: -------------------------------------------------------------------------------- 1 | import Chip from './Chip.vue' 2 | import ChipSet from './ChipSet.vue' 3 | import './styles.scss' 4 | 5 | import { initPlugin } from '../' 6 | 7 | const plugin = { 8 | install (vm) { 9 | vm.component('m-chip', Chip) 10 | vm.component('m-chip-set', ChipSet) 11 | } 12 | } 13 | export default plugin 14 | 15 | initPlugin(plugin) 16 | -------------------------------------------------------------------------------- /components/chips/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/chips/mdc-chips"; 2 | -------------------------------------------------------------------------------- /components/dialog/__test__/Dialog.spec.js: -------------------------------------------------------------------------------- 1 | import 'mutationobserver-shim' 2 | import { mount } from '@vue/test-utils' 3 | import Dialog from '../Dialog.vue' 4 | import Vue from 'vue' 5 | 6 | describe('Dialog', () => { 7 | it('should mount', () => { 8 | const wrapper = mount(Dialog) 9 | expect(wrapper.isVueInstance()).toBeTruthy() 10 | }) 11 | 12 | it('should render with no prop', () => { 13 | const wrapper = mount(Dialog) 14 | expect(wrapper).toMatchSnapshot() 15 | expect(wrapper.classes()).toContain('mdc-dialog') 16 | }) 17 | 18 | it('should render as scrollable', () => { 19 | const wrapper = mount(Dialog, { 20 | propsData: { 21 | scrollable: true 22 | } 23 | }) 24 | expect(wrapper).toMatchSnapshot() 25 | expect(wrapper.classes()).toContain('mdc-dialog--scrollable') 26 | }) 27 | 28 | it('should render and emit', async () => { 29 | const wrapper = mount(Dialog, { 30 | propsData: { 31 | open: false 32 | } 33 | }) 34 | 35 | wrapper.setProps({ open: true }) 36 | 37 | await Vue.nextTick() 38 | 39 | expect(wrapper).toMatchSnapshot() 40 | expect(wrapper.emittedByOrder().map(e => e.name)).toContain('opening') 41 | expect(wrapper.vm.$data.mdcDialog).toBeDefined() 42 | expect(wrapper.vm.$data.mdcDialog.isOpen).toBe(true) 43 | expect(wrapper.isVisible()).toBe(true) 44 | 45 | wrapper.find('.mdc-dialog__scrim').trigger('click') 46 | expect(wrapper).toMatchSnapshot() 47 | expect(wrapper.emittedByOrder().map(e => e.name)).toContain('closing') 48 | expect(wrapper.emitted().closing[0]).toEqual([{ action: 'close' }]) 49 | expect(wrapper.vm.$data.mdcDialog.isOpen).toBe(false) 50 | }) 51 | }) 52 | -------------------------------------------------------------------------------- /components/dialog/__test__/__snapshots__/Dialog.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Dialog should render and emit 1`] = ` 4 |
5 |
6 |
7 | 8 | 9 | 10 |
11 |
12 |
13 |
14 | `; 15 | 16 | exports[`Dialog should render and emit 2`] = ` 17 |
18 |
19 |
20 | 21 | 22 | 23 |
24 |
25 |
26 |
27 | `; 28 | 29 | exports[`Dialog should render as scrollable 1`] = ` 30 |
31 |
32 |
33 | 34 | 35 | 36 |
37 |
38 |
39 |
40 | `; 41 | 42 | exports[`Dialog should render with no prop 1`] = ` 43 |
44 |
45 |
46 | 47 | 48 | 49 |
50 |
51 |
52 |
53 | `; 54 | -------------------------------------------------------------------------------- /components/dialog/index.js: -------------------------------------------------------------------------------- 1 | import Dialog from './Dialog.vue' 2 | import './styles.scss' 3 | 4 | import { initPlugin } from '../' 5 | 6 | const plugin = { 7 | install (vm) { 8 | vm.component('m-dialog', Dialog) 9 | } 10 | } 11 | export default plugin 12 | 13 | initPlugin(plugin) 14 | -------------------------------------------------------------------------------- /components/dialog/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/dialog/mdc-dialog"; -------------------------------------------------------------------------------- /components/drawer/DrawerAppContent.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /components/drawer/DrawerContent.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 18 | -------------------------------------------------------------------------------- /components/drawer/DrawerHeader.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 39 | -------------------------------------------------------------------------------- /components/drawer/DrawerList.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | -------------------------------------------------------------------------------- /components/drawer/DrawerScrim.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | -------------------------------------------------------------------------------- /components/drawer/__test__/__snapshots__/Drawer.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Drawer should render as dismissible 1`] = ` 4 | 7 | `; 8 | 9 | exports[`Drawer should render as modal 1`] = ` 10 | 13 | `; 14 | 15 | exports[`Drawer should render with no prop 1`] = ` 16 | 19 | `; 20 | 21 | exports[`Drawer should render with subtitle 1`] = ` 22 | 30 | `; 31 | 32 | exports[`Drawer should render with title 1`] = ` 33 | 41 | `; 42 | 43 | exports[`DrawerAppContent should render with no prop 1`] = `
`; 44 | 45 | exports[`DrawerContent should render with no prop 1`] = `
123
`; 46 | 47 | exports[`DrawerHeader should render with no prop 1`] = ` 48 |
49 | 50 | 123
51 | `; 52 | 53 | exports[`DrawerHeader should render with subtitle 1`] = ` 54 |
55 | 56 |
57 | title 58 |
59 |
60 | `; 61 | 62 | exports[`DrawerHeader should render with title 1`] = ` 63 |
64 |

65 | title 66 |

67 | 68 |
69 | `; 70 | 71 | exports[`DrawerScrim should render with no prop 1`] = `
`; 72 | -------------------------------------------------------------------------------- /components/drawer/index.js: -------------------------------------------------------------------------------- 1 | import DrawerContent from './DrawerContent.vue' 2 | import DrawerHeader from './DrawerHeader.vue' 3 | import Drawer from './Drawer.vue' 4 | import DrawerScrim from './DrawerScrim.vue' 5 | import DrawerAppContent from './DrawerAppContent.vue' 6 | import DrawerList from './DrawerList.vue' 7 | import './styles.scss' 8 | 9 | import { initPlugin } from '../' 10 | 11 | const plugin = { 12 | install (vm) { 13 | vm.component('m-drawer-content', DrawerContent) 14 | vm.component('m-drawer-header', DrawerHeader) 15 | vm.component('m-drawer', Drawer) 16 | vm.component('m-drawer-scrim', DrawerScrim) 17 | vm.component('m-drawer-app-content', DrawerAppContent) 18 | vm.component('m-drawer-list', DrawerList) 19 | } 20 | } 21 | export default plugin 22 | 23 | initPlugin(plugin) 24 | -------------------------------------------------------------------------------- /components/drawer/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/drawer/mdc-drawer"; -------------------------------------------------------------------------------- /components/elevation/Elevation.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 32 | -------------------------------------------------------------------------------- /components/elevation/README.md: -------------------------------------------------------------------------------- 1 | ## Elevation 2 | 3 | Material Components Vue provides a customized directive `v-elevation` to provide any components with elevation or shadow. 4 | 5 | ### Minimal Usage 6 | 7 | ```html 8 | Button 9 | ``` 10 | 11 | ### Add transition between different elevations 12 | 13 | ```html 14 | Button 15 | ``` 16 | 17 | ```js 18 | data () { 19 | return { 20 | elevation: 1 // change this value to see the transition 21 | } 22 | } 23 | ``` 24 | 25 | Or you can use a component. 26 | 27 | ### Markup 28 | 29 | ```html 30 | 31 | elevated 32 | 33 | ``` 34 | ### Props 35 | 36 | | Prop | Type | Default | Required | Description | 37 | |------|------|---------|----------|-------------| 38 | | level | Number | - | true | level of elevation between 1 and 24 | 39 | | transition | Boolean | - | false | whether there should be transition between elevation levels | 40 | 41 | ### Slots 42 | 43 | | Slot | Prop dependencies | Description | 44 | |------|-------------------|-------------| 45 | | default | - | elevation content | 46 | 47 | ### Reference 48 | 49 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-elevation 50 | -------------------------------------------------------------------------------- /components/elevation/index.js: -------------------------------------------------------------------------------- 1 | import Elevation from './Elevation.vue' 2 | import './styles.scss' 3 | 4 | import { initPlugin } from '../' 5 | 6 | const plugin = { 7 | install (vm) { 8 | vm.component('m-elevation', Elevation) 9 | vm.directive('elevation', { 10 | bind: function (el, binding) { 11 | if (binding.value != null) { 12 | const n = Number(binding.value) 13 | el.classList.add(`mdc-elevation--z${n}`) 14 | } 15 | if (binding.modifiers.transition) { 16 | el.classList.add('mdc-elevation-transition') 17 | } 18 | }, 19 | componentUpdated: function (el, binding) { 20 | if (Number(binding.oldValue) !== Number(binding.value)) { 21 | if (binding.oldValue != null) { 22 | const n = Number(binding.oldValue) 23 | el.classList.remove(`mdc-elevation--z${n}`) 24 | } 25 | if (binding.value != null) { 26 | const n = Number(binding.value) 27 | el.classList.add(`mdc-elevation--z${n}`) 28 | } 29 | } 30 | if (!binding.modifiers.transition && el.classList.contains('mdc-elevation-transition')) { 31 | el.classList.remove('mdc-elevation-transition') 32 | } 33 | if (binding.modifiers.transition && !el.classList.contains('mdc-elevation-transition')) { 34 | el.classList.add('mdc-elevation-transition') 35 | } 36 | }, 37 | unbind: function (el, binding) { 38 | if (binding.value != null) { 39 | const n = Number(binding.value) 40 | el.classList.remove(`mdc-elevation--z${n}`) 41 | } 42 | if (binding.modifiers.transition) { 43 | el.classList.remove('mdc-elevation-transition') 44 | } 45 | } 46 | }) 47 | } 48 | } 49 | export default plugin 50 | 51 | initPlugin(plugin) 52 | -------------------------------------------------------------------------------- /components/elevation/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/elevation/mdc-elevation"; -------------------------------------------------------------------------------- /components/fab/README.md: -------------------------------------------------------------------------------- 1 | ## Fab 2 | 3 | ### Markup 4 | 5 | #### Basic Usage 6 | 7 | ```html 8 | 9 | 10 | 11 | ``` 12 | 13 | #### Extended FAB 14 | 15 | ```html 16 | 17 | 18 | Create 19 | 20 | ``` 21 | 22 | #### Using Font Awesome 23 | 24 | ```html 25 | 26 | 27 | 28 | ``` 29 | 30 | ### Props 31 | 32 | | Prop | Type | Default | Description | 33 | |------|------|---------|-------------| 34 | | mini | Boolean | false | modifies the FAB to a smaller size | 35 | | absoluteRight | Boolean | false | **Might be deprecated in future version and not recommended.** Whether the fab should be rendered on the bottom right | 36 | | exited | Boolean | false | animates the fab out of view | 37 | | ripple | Boolean | true | use js ripple or not | 38 | | href | String | '' | render as `` if presented | 39 | 40 | Events and attributes are mapped to the inner button element. 41 | 42 | ### Slots 43 | 44 | | Slot | Description | 45 | |------|-------------| 46 | | default | fab content | 47 | | icon | leading icon in extended fab | 48 | | trailingIcon | trailing icon in extended fab | 49 | 50 | ### Additional Information 51 | 52 | #### Positioning 53 | 54 | Developers must position `` as needed within their application’s design. 55 | 56 | ```html 57 | 71 | 72 | 73 | 74 | ``` 75 | 76 | ## Reference 77 | 78 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-fab 79 | -------------------------------------------------------------------------------- /components/fab/__test__/Fab.spec.js: -------------------------------------------------------------------------------- 1 | import 'mutationobserver-shim' 2 | import { mount } from '@vue/test-utils' 3 | import Fab from '../Fab.vue' 4 | import Vue from 'vue' 5 | 6 | describe('Fab', () => { 7 | it('should mount', () => { 8 | const wrapper = mount(Fab) 9 | expect(wrapper.isVueInstance()).toBeTruthy() 10 | expect(wrapper.vm.$data.mdcRipple).toBeDefined() 11 | expect(wrapper.vm.$data.slotObserver).toBeDefined() 12 | }) 13 | 14 | it('should render with no prop', () => { 15 | const wrapper = mount(Fab) 16 | expect(wrapper).toMatchSnapshot() 17 | expect(wrapper.classes()).toContain('mdc-fab') 18 | }) 19 | 20 | it('should render as mini', () => { 21 | const wrapper = mount(Fab, { 22 | propsData: { 23 | mini: true 24 | } 25 | }) 26 | expect(wrapper).toMatchSnapshot() 27 | expect(wrapper.classes()).toContain('mdc-fab--mini') 28 | }) 29 | 30 | it('should render as exited', () => { 31 | const wrapper = mount(Fab, { 32 | propsData: { 33 | exited: true 34 | } 35 | }) 36 | expect(wrapper).toMatchSnapshot() 37 | expect(wrapper.classes()).toContain('mdc-fab--exited') 38 | }) 39 | 40 | it('should render as extended', async () => { 41 | const wrapper = mount(Fab, { 42 | slots: { 43 | default: 'create' 44 | } 45 | }) 46 | await Vue.nextTick() 47 | expect(wrapper).toMatchSnapshot() 48 | expect(wrapper.classes()).toContain('mdc-fab--extended') 49 | }) 50 | 51 | it('should render as absolute right', () => { 52 | const wrapper = mount(Fab, { 53 | propsData: { 54 | absoluteRight: true 55 | } 56 | }) 57 | expect(wrapper).toMatchSnapshot() 58 | expect(wrapper.classes()).toContain('mdc-fab--absolute-right') 59 | }) 60 | 61 | it('should render without ripple', () => { 62 | const wrapper = mount(Fab, { 63 | propsData: { 64 | ripple: false 65 | } 66 | }) 67 | expect(wrapper).toMatchSnapshot() 68 | expect(wrapper.vm.$data.mdcRipple).toBeUndefined() 69 | }) 70 | }) 71 | -------------------------------------------------------------------------------- /components/fab/__test__/__snapshots__/Fab.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Fab should render as absolute right 1`] = ``; 4 | 5 | exports[`Fab should render as exited 1`] = ``; 6 | 7 | exports[`Fab should render as extended 1`] = ``; 8 | 9 | exports[`Fab should render as mini 1`] = ``; 10 | 11 | exports[`Fab should render with no prop 1`] = ``; 12 | 13 | exports[`Fab should render without ripple 1`] = ``; 14 | -------------------------------------------------------------------------------- /components/fab/index.js: -------------------------------------------------------------------------------- 1 | import Fab from './Fab.vue' 2 | import './styles.scss' 3 | 4 | import { initPlugin } from '../' 5 | 6 | const plugin = { 7 | install (vm) { 8 | vm.component('m-fab', Fab) 9 | } 10 | } 11 | export default plugin 12 | 13 | initPlugin(plugin) 14 | -------------------------------------------------------------------------------- /components/fab/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/fab/mdc-fab"; 2 | 3 | .mdc-fab--absolute-right.mdc-fab--absolute-right { 4 | position: fixed; 5 | bottom: 1rem; 6 | right: 1rem; 7 | } 8 | 9 | @media(min-width: 1024px) { 10 | .mdc-fab--absolute-right.mdc-fab--absolute-right { 11 | bottom: 1.5rem; 12 | right: 1.5rem; 13 | } 14 | } -------------------------------------------------------------------------------- /components/floating-label/FloatingLabel.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 68 | -------------------------------------------------------------------------------- /components/floating-label/README.md: -------------------------------------------------------------------------------- 1 | ## FloatingLabel 2 | 3 | ### Markup 4 | 5 | 6 | ```html 7 | 8 | Textfield label 9 | 10 | 11 | ``` 12 | 13 | ### Props 14 | 15 | | Prop | Type | Default | Description | 16 | |------|------|---------|-------------| 17 | | floatAbove | Boolean | false | label is floating above | 18 | | absoluteRight | Boolean | false | shakes the label | 19 | 20 | ### Slots 21 | 22 | | Slot | Description | 23 | |------|-------------| 24 | | default | label content | 25 | 26 | ### Reference 27 | 28 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-floating-label 29 | 30 | 31 | -------------------------------------------------------------------------------- /components/floating-label/__test__/FloatingLabel.spec.js: -------------------------------------------------------------------------------- 1 | import 'mutationobserver-shim' 2 | import { mount } from '@vue/test-utils' 3 | import FloatingLabel from '../FloatingLabel.vue' 4 | 5 | describe('FloatingLabel', () => { 6 | it('should mount', () => { 7 | const wrapper = mount(FloatingLabel) 8 | expect(wrapper.isVueInstance()).toBeTruthy() 9 | expect(wrapper.vm.$data.mdcFloatingLabel).toBeDefined() 10 | }) 11 | 12 | it('should render with no prop', () => { 13 | const wrapper = mount(FloatingLabel) 14 | expect(wrapper).toMatchSnapshot() 15 | expect(wrapper.classes()).toContain('mdc-floating-label') 16 | }) 17 | 18 | it('should render with floatAbove', () => { 19 | const wrapper = mount(FloatingLabel, { 20 | propsData: { 21 | floatAbove: true 22 | } 23 | }) 24 | expect(wrapper).toMatchSnapshot() 25 | expect(wrapper.classes()).toContain('mdc-floating-label--float-above') 26 | }) 27 | 28 | it('should render with shake', () => { 29 | const wrapper = mount(FloatingLabel, { 30 | propsData: { 31 | shake: true 32 | } 33 | }) 34 | expect(wrapper).toMatchSnapshot() 35 | expect(wrapper.classes()).toContain('mdc-floating-label--shake') 36 | }) 37 | }) 38 | -------------------------------------------------------------------------------- /components/floating-label/__test__/__snapshots__/FloatingLabel.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`FloatingLabel should render with floatAbove 1`] = ``; 4 | 5 | exports[`FloatingLabel should render with no prop 1`] = ``; 6 | 7 | exports[`FloatingLabel should render with shake 1`] = ``; 8 | -------------------------------------------------------------------------------- /components/floating-label/index.js: -------------------------------------------------------------------------------- 1 | import FloatingLabel from './FloatingLabel.vue' 2 | import './styles.scss' 3 | 4 | import { initPlugin } from '../' 5 | 6 | const plugin = { 7 | install (vm) { 8 | vm.component('m-floating-label', FloatingLabel) 9 | } 10 | } 11 | export default plugin 12 | 13 | initPlugin(plugin) 14 | -------------------------------------------------------------------------------- /components/floating-label/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/floating-label/mdc-floating-label"; 2 | -------------------------------------------------------------------------------- /components/form-field/FormField.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 55 | -------------------------------------------------------------------------------- /components/form-field/README.md: -------------------------------------------------------------------------------- 1 | ## FormField 2 | 3 | ### Markup 4 | 5 | ```html 6 | 7 | 8 | 9 | 10 | ``` 11 | ### Props 12 | 13 | | Prop | Type | Default | Required | Description | 14 | |------|------|---------|----------|-------------| 15 | | alignEnd | Boolean | - | false | label before input | 16 | 17 | ### Slots 18 | 19 | | Slot | Prop dependencies | Description | 20 | |------|-------------------|-------------| 21 | | default | - | label and input content | 22 | 23 | ### Reference 24 | 25 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-form-field 26 | -------------------------------------------------------------------------------- /components/form-field/index.js: -------------------------------------------------------------------------------- 1 | import FormField from './FormField.vue' 2 | import './styles.scss' 3 | 4 | import { initPlugin } from '../' 5 | 6 | const plugin = { 7 | install (vm) { 8 | vm.component('m-form-field', FormField) 9 | } 10 | } 11 | export default plugin 12 | 13 | initPlugin(plugin) 14 | -------------------------------------------------------------------------------- /components/form-field/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/form-field/mdc-form-field"; -------------------------------------------------------------------------------- /components/grid-list/GridList.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 77 | -------------------------------------------------------------------------------- /components/grid-list/GridListTile.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 75 | -------------------------------------------------------------------------------- /components/grid-list/README.md: -------------------------------------------------------------------------------- 1 | ## GridList 2 | 3 | ### Markup 4 | 5 | ```html 6 | 7 | 8 | Edit 9 | Supporttext 10 | 11 | 12 | Like you 13 | Like 14 | 15 | 16 | 17 | ``` 18 | 19 | ### Props 20 | 21 | | Prop | Type | Default | Required | Description | 22 | |------|------|---------|----------|-------------| 23 | | headerCaption | Boolean | - | false | header instead of footer caption | 24 | | twoLineCaption | Boolean | - | false | twoline instead of oneline caption | 25 | | smallGutter | Boolean | - | false | 1px instead of 4px padding | 26 | | startIcon | Boolean | - | false | caption with start icon | 27 | | endIcon | Boolean | - | false | caption with end icon | 28 | | ratio | String | '1x1' | false | grid tile ratio can be '1x1', '16x9', '2x3', '3x2', '4x3' and '3x4' | 29 | 30 | ### Slots 31 | 32 | | Slot | Prop dependencies | Description | 33 | |------|-------------------|-------------| 34 | | default | - | grid tiles | 35 | 36 | ## GridListTile 37 | 38 | ### Props 39 | 40 | | Prop | Type | Default | Description | 41 | |------|------|---------|-------------| 42 | | imgSrc | String | false | image source | 43 | 44 | ### Slots 45 | 46 | | Slot | Prop dependencies | Description | 47 | |------|-------------------|-------------| 48 | | default | - | grid tile title section | 49 | | primary | imgSrc | primary content if image is not provided as source url | 50 | | supporttext | - | supporting text for the caption | 51 | | icon | - | icon component | 52 | 53 | ### Reference 54 | 55 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-grid-list 56 | -------------------------------------------------------------------------------- /components/grid-list/index.js: -------------------------------------------------------------------------------- 1 | import GridList from './GridList.vue' 2 | import GridListTile from './GridListTile.vue' 3 | import './styles.scss' 4 | 5 | import { initPlugin } from '../' 6 | 7 | const plugin = { 8 | install (vm) { 9 | vm.component('m-grid-list', GridList) 10 | vm.component('m-grid-tile', GridListTile) 11 | } 12 | } 13 | export default plugin 14 | 15 | initPlugin(plugin) 16 | -------------------------------------------------------------------------------- /components/grid-list/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/grid-list/mdc-grid-list"; -------------------------------------------------------------------------------- /components/icon-button/README.md: -------------------------------------------------------------------------------- 1 | ## IconButton 2 | 3 | This component doesn't contain any icon CSS classes. You can use the slot variant with [Icon](../icon/README.md) or 4 | e.g. SVGs. When you want to use toggling props you have to provide CSS for your Icons e.g. [Font Awesome](https://fontawesome.com/). 5 | 6 | ### Markup 7 | 8 | #### Using SVG 9 | 10 | ```html 11 | 12 | ... 13 | 14 | 15 | 16 | ... 17 | ... 18 | 19 | ``` 20 | 21 | #### Using Material Icons 22 | 23 | ```html 24 | 25 | 26 | 27 | favorite 28 | favorite_border 29 | 30 | ``` 31 | 32 | #### Using Font Awesome 33 | 34 | ```html 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | ``` 44 | 45 | ### Script 46 | 47 | ```javascript 48 | data() { 49 | return { 50 | iconToggle: false 51 | } 52 | } 53 | ``` 54 | 55 | ### Props 56 | 57 | | Prop | Type | Default | Description | 58 | |------|------|---------|-------------| 59 | | value | Boolean | false | toggle state (could be v-modeled) | 60 | | href | String | '' | render as `` if presented. Not recommended to use in icon button toggle | 61 | | icon | String | '' | Material Icon name. Similar to `icon` in ``. Omit this if you're using other icon libraries. | 62 | | ripple | Boolean | true | Whether to use js ripple or not. Notice that the icon button toggle always has a ripple so this prop is always omitted if `toggleOn` and `toggleOff` slots are presented. | 63 | | unbounded | Boolean | true | The `unbounded` prop of the ripple. | 64 | 65 | Non prop attributes and events are mapped to the inner button element. 66 | 67 | ### Slots 68 | 69 | | Slot | Description | 70 | |------|-------------| 71 | | default | button icon | 72 | | toggleOn | toggle icon for 'on' state | 73 | | toggleOff | toggle icon for 'off' state | 74 | 75 | ### Reference 76 | 77 | - https://material.io/icons 78 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-icon-button -------------------------------------------------------------------------------- /components/icon-button/__tests__/IconButton.spec.js: -------------------------------------------------------------------------------- 1 | import 'mutationobserver-shim' 2 | import { mount } from '@vue/test-utils' 3 | import IconButton from '../IconButton.vue' 4 | 5 | describe('IconButton', () => { 6 | it('should mount', () => { 7 | const wrapper = mount(IconButton) 8 | expect(wrapper.isVueInstance()).toBeTruthy() 9 | expect(wrapper.vm.$data.slotObserver).toBeDefined() 10 | }) 11 | 12 | it('should render with no prop', () => { 13 | const wrapper = mount(IconButton) 14 | expect(wrapper).toMatchSnapshot() 15 | expect(wrapper.classes()).toContain('mdc-icon-button') 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /components/icon-button/__tests__/__snapshots__/IconButton.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`IconButton should render with no prop 1`] = ` 4 | 7 | `; 8 | -------------------------------------------------------------------------------- /components/icon-button/index.js: -------------------------------------------------------------------------------- 1 | import IconButton from './IconButton.vue' 2 | import './styles.scss' 3 | 4 | import { initPlugin } from '../' 5 | 6 | const plugin = { 7 | install (vm) { 8 | vm.component('m-icon-button', IconButton) 9 | } 10 | } 11 | export default plugin 12 | 13 | initPlugin(plugin) 14 | -------------------------------------------------------------------------------- /components/icon-button/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/icon-button/mdc-icon-button"; -------------------------------------------------------------------------------- /components/icon/Icon.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 38 | -------------------------------------------------------------------------------- /components/icon/README.md: -------------------------------------------------------------------------------- 1 | ## Icon 2 | 3 | ### Markup 4 | 5 | ```html 6 | 7 | ``` 8 | 9 | ### Script 10 | 11 | ```javascript 12 | methods: { 13 | clicked() { 14 | // do something 15 | } 16 | } 17 | ``` 18 | 19 | ### Props 20 | 21 | | Prop | Type | Required | Description | 22 | |------|------|----------|-------------| 23 | | icon | String | true | material icon name | 24 | 25 | ### Reference 26 | 27 | - https://material.io/icons 28 | -------------------------------------------------------------------------------- /components/icon/index.js: -------------------------------------------------------------------------------- 1 | import Icon from './Icon.vue' 2 | 3 | import { initPlugin } from '../' 4 | 5 | const plugin = { 6 | install (vm) { 7 | vm.component('m-icon', Icon) 8 | } 9 | } 10 | export default plugin 11 | 12 | initPlugin(plugin) 13 | -------------------------------------------------------------------------------- /components/image-list/ImageList.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 48 | -------------------------------------------------------------------------------- /components/image-list/ImageListItem.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 59 | -------------------------------------------------------------------------------- /components/image-list/README.md: -------------------------------------------------------------------------------- 1 | ## Image List 2 | 3 | ### Markup 4 | 5 | ```html 6 | 9 | 10 | Cat 11 | Cat 12 | 13 | 14 | Cat 15 | Cat 16 | 17 | 18 | Cat 19 | Cat 20 | 21 | 22 | Cat 23 | Cat 24 | 25 | 26 | 27 | ``` 28 | 29 | ### Props 30 | 31 | | Prop | Type | Default | Description | 32 | |------|------|---------|-------------| 33 | | column | Number | 0 | columns per line, `0` means not to shrink or grow | 34 | | masonry | Boolean | false | masonry if `true`, standard if `false` | 35 | | textProtection | Boolean | false | label will be positioned in a scrim overlaying each image | 36 | 37 | ### Slots 38 | 39 | | Slot | Description | 40 | |------|-------------| 41 | | default | should be `` | 42 | 43 | ## Image List Item 44 | 45 | ### Props 46 | 47 | | Prop | Type | Default | Description | 48 | |------|------|---------|-------------| 49 | | adjustAspectRatio | Boolean | true | adjusts the ratio of images for standard columns | 50 | 51 | ### Slots 52 | 53 | | Slot | Description | 54 | |------|-------------| 55 | | default | image label | 56 | | image | img element | 57 | 58 | ### Reference 59 | 60 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-image-list 61 | -------------------------------------------------------------------------------- /components/image-list/__tests__/__snapshots__/ImageList.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`ImageList should render as masonry 1`] = `
    `; 4 | 5 | exports[`ImageList should render as standard 1`] = `
      `; 6 | 7 | exports[`ImageList should render with no prop 1`] = `
        `; 8 | 9 | exports[`ImageList should render with text-protection 1`] = `
          `; 10 | 11 | exports[`ImageListItem should render with img 1`] = ` 12 |
        • 13 |
          Cat
          14 | 15 |
        • 16 | `; 17 | 18 | exports[`ImageListItem should render with no prop 1`] = ` 19 |
        • 20 |
          21 | 22 |
        • 23 | `; 24 | 25 | exports[`ImageListItem should render without adjust aspect ratio 1`] = ` 26 |
        • 27 | 28 |
        • 29 | `; 30 | -------------------------------------------------------------------------------- /components/image-list/index.js: -------------------------------------------------------------------------------- 1 | import ImageList from './ImageList.vue' 2 | import ImageListItem from './ImageListItem.vue' 3 | 4 | import { initPlugin } from '../' 5 | 6 | const plugin = { 7 | install (vm) { 8 | vm.component('m-image-list', ImageList) 9 | vm.component('m-image-list-item', ImageListItem) 10 | } 11 | } 12 | export default plugin 13 | 14 | initPlugin(plugin) 15 | -------------------------------------------------------------------------------- /components/image-list/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/image-list/mdc-image-list"; 2 | 3 | .image-list-standard-1 { 4 | @include mdc-image-list-standard-columns(1); 5 | } 6 | .image-list-standard-2 { 7 | @include mdc-image-list-standard-columns(2); 8 | } 9 | .image-list-standard-3 { 10 | @include mdc-image-list-standard-columns(3); 11 | } 12 | .image-list-standard-4 { 13 | @include mdc-image-list-standard-columns(4); 14 | } 15 | .image-list-standard-5 { 16 | @include mdc-image-list-standard-columns(5); 17 | } 18 | .image-list-standard-6 { 19 | @include mdc-image-list-standard-columns(6); 20 | } 21 | .image-list-standard-7 { 22 | @include mdc-image-list-standard-columns(7); 23 | } 24 | .image-list-standard-8 { 25 | @include mdc-image-list-standard-columns(8); 26 | } 27 | .image-list-standard-9 { 28 | @include mdc-image-list-standard-columns(9); 29 | } 30 | .image-list-standard-10 { 31 | @include mdc-image-list-standard-columns(10); 32 | } 33 | .image-list-standard-11 { 34 | @include mdc-image-list-standard-columns(11); 35 | } 36 | .image-list-standard-12 { 37 | @include mdc-image-list-standard-columns(12); 38 | } 39 | 40 | .image-list-masonry-1 { 41 | @include mdc-image-list-masonry-columns(1); 42 | } 43 | .image-list-masonry-2 { 44 | @include mdc-image-list-masonry-columns(2); 45 | } 46 | .image-list-masonry-3 { 47 | @include mdc-image-list-masonry-columns(3); 48 | } 49 | .image-list-masonry-4 { 50 | @include mdc-image-list-masonry-columns(4); 51 | } 52 | .image-list-masonry-5 { 53 | @include mdc-image-list-masonry-columns(5); 54 | } 55 | .image-list-masonry-6 { 56 | @include mdc-image-list-masonry-columns(6); 57 | } 58 | .image-list-masonry-7 { 59 | @include mdc-image-list-masonry-columns(7); 60 | } 61 | .image-list-masonry-8 { 62 | @include mdc-image-list-masonry-columns(8); 63 | } 64 | .image-list-masonry-9 { 65 | @include mdc-image-list-masonry-columns(9); 66 | } 67 | .image-list-masonry-10 { 68 | @include mdc-image-list-masonry-columns(10); 69 | } 70 | .image-list-masonry-11 { 71 | @include mdc-image-list-masonry-columns(11); 72 | } 73 | .image-list-masonry-12 { 74 | @include mdc-image-list-masonry-columns(12); 75 | } 76 | -------------------------------------------------------------------------------- /components/index.js: -------------------------------------------------------------------------------- 1 | export * from './initPlugin.js' 2 | -------------------------------------------------------------------------------- /components/initPlugin.js: -------------------------------------------------------------------------------- 1 | export function initPlugin (plugin) { 2 | if (typeof window !== 'undefined' && window.Vue) { 3 | window.Vue.use(plugin) 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /components/layout-grid/LayoutGrid.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 37 | -------------------------------------------------------------------------------- /components/layout-grid/LayoutGridCell.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 61 | -------------------------------------------------------------------------------- /components/layout-grid/LayoutGridInner.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /components/layout-grid/README.md: -------------------------------------------------------------------------------- 1 | ## LayoutGrid 2 | 3 | ### Markup 4 | 5 | ```html 6 | 7 | 8 | 9 | Cell 1 10 | 11 | 12 | Cell 2 13 | 14 | 15 | 16 | ``` 17 | 18 | ### Props 19 | 20 | | Prop | Type | Default | Required | Description | 21 | |------|------|---------|----------|-------------| 22 | | align | String | - | false | alignment of grid: 'left' or 'right' | 23 | | fixedColumnWidth | Boolean | - | false | fixed column width | 24 | 25 | ### Slots 26 | 27 | | Slot | Description | 28 | |------|-------------| 29 | | default | should be LayoutInnerGrid | 30 | 31 | ## LayoutGridCell 32 | 33 | ### Props 34 | 35 | | Prop | Type | Default | Required | Description | 36 | |------|------|---------|----------|-------------| 37 | | span | Number | - | false | cell span from 1 to 12 | 38 | | spanDesktop | Number | - | false | cell span from 1 to 12 on desktop | 39 | | spanTablet | Number | - | false | cell span from 1 to 12 on tablet | 40 | | span Phone | Number | - | false | cell span from 1 to 12 on phone | 41 | | order | Number | - | false | cell order from 1 to 12 | 42 | | align | String | - | false | cell alignment could be 'top', 'middle' and 'bottom' | 43 | 44 | ### Slots 45 | 46 | | Slot | Description | 47 | |------|-------------| 48 | | default | content of GridCell | 49 | 50 | ## LayoutGridInner 51 | 52 | ### Slots 53 | 54 | | Slot | Description | 55 | |------|-------------| 56 | | default | should be GridCells | 57 | 58 | ### Reference 59 | 60 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-layout-grid 61 | -------------------------------------------------------------------------------- /components/layout-grid/index.js: -------------------------------------------------------------------------------- 1 | import LayoutGrid from './LayoutGrid.vue' 2 | import LayoutGridCell from './LayoutGridCell.vue' 3 | import LayoutGridInner from './LayoutGridInner.vue' 4 | import './styles.scss' 5 | 6 | import { initPlugin } from '../' 7 | 8 | const plugin = { 9 | install (vm) { 10 | vm.component('m-layout-grid', LayoutGrid) 11 | vm.component('m-layout-grid-cell', LayoutGridCell) 12 | vm.component('m-layout-grid-inner', LayoutGridInner) 13 | } 14 | } 15 | export default plugin 16 | 17 | initPlugin(plugin) 18 | -------------------------------------------------------------------------------- /components/layout-grid/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/layout-grid/mdc-layout-grid"; -------------------------------------------------------------------------------- /components/line-ripple/LineRipple.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 69 | -------------------------------------------------------------------------------- /components/line-ripple/README.md: -------------------------------------------------------------------------------- 1 | ## LineRipple 2 | 3 | ### Markup 4 | 5 | ```html 6 | 7 | ``` 8 | 9 | ### Script 10 | 11 | ```javascript 12 | this.$refs.rp.activate() 13 | ``` 14 | 15 | ### Methods 16 | 17 | | Method | Description | 18 | |--------|-------------| 19 | | activate() | activate the line ripple | 20 | | deactivate() | deactivate the line ripple | 21 | | setRippleCenter(xCoordinate) | set ripple center by x-coordinate | 22 | 23 | 24 | ### Reference 25 | 26 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-line-ripple -------------------------------------------------------------------------------- /components/line-ripple/index.js: -------------------------------------------------------------------------------- 1 | import LineRipple from './LineRipple.vue' 2 | import './styles.scss' 3 | 4 | import { initPlugin } from '../' 5 | 6 | const plugin = { 7 | install (vm) { 8 | vm.component('m-line-ripple', LineRipple) 9 | } 10 | } 11 | export default plugin 12 | 13 | initPlugin(plugin) 14 | -------------------------------------------------------------------------------- /components/line-ripple/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/line-ripple/mdc-line-ripple"; -------------------------------------------------------------------------------- /components/linear-progress/LinearProgress.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 83 | -------------------------------------------------------------------------------- /components/linear-progress/README.md: -------------------------------------------------------------------------------- 1 | ## LinearProgress 2 | 3 | ### Markup 4 | 5 | ```html 6 | 11 | ``` 12 | 13 | ### Script 14 | 15 | ```javascript 16 | data () { 17 | return { 18 | isProgressOpen: true 19 | } 20 | } 21 | ``` 22 | 23 | ### Props 24 | 25 | | Prop | Type | Default | Required | Description | 26 | |------|------|---------|----------|-------------| 27 | | open | Boolean | false | - | linear progress starts in open state | 28 | | indeterminate | Boolean | false | - | indeterminate state | 29 | | reverse | Boolean | false | - | reverse direction of progress | 30 | | progress | Number | - | false | progress value between 0 and 1 | 31 | | buffer | Number | - | false | buffer value between 0 and 1 | 32 | 33 | ### Reference 34 | 35 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-linear-progress 36 | -------------------------------------------------------------------------------- /components/linear-progress/__test__/LinearProgress.spec.js: -------------------------------------------------------------------------------- 1 | import 'mutationobserver-shim' 2 | import { mount } from '@vue/test-utils' 3 | import LinearProgress from '../LinearProgress.vue' 4 | 5 | describe('LinearProgress', () => { 6 | it('should mount', () => { 7 | const wrapper = mount(LinearProgress) 8 | expect(wrapper.isVueInstance()).toBeTruthy() 9 | expect(wrapper.vm.$data.mdcLinearProgress).toBeDefined() 10 | }) 11 | 12 | it('should render with no prop', () => { 13 | const wrapper = mount(LinearProgress) 14 | expect(wrapper).toMatchSnapshot() 15 | expect(wrapper.classes()).toContain('mdc-linear-progress') 16 | expect(wrapper.classes()).toContain('mdc-linear-progress--closed') 17 | }) 18 | 19 | it('should render as open', () => { 20 | const wrapper = mount(LinearProgress, { 21 | propsData: { 22 | open: true 23 | } 24 | }) 25 | expect(wrapper).toMatchSnapshot() 26 | expect(wrapper.isVisible()).toBe(true) 27 | }) 28 | 29 | it('should render as reversed', () => { 30 | const wrapper = mount(LinearProgress, { 31 | propsData: { 32 | open: true, 33 | reverse: true 34 | } 35 | }) 36 | expect(wrapper).toMatchSnapshot() 37 | expect(wrapper.classes()).toContain('mdc-linear-progress--reversed') 38 | }) 39 | 40 | it('should render as indeterminate', () => { 41 | const wrapper = mount(LinearProgress, { 42 | propsData: { 43 | open: true, 44 | indeterminate: true 45 | } 46 | }) 47 | expect(wrapper).toMatchSnapshot() 48 | expect(wrapper.classes()).toContain('mdc-linear-progress--indeterminate') 49 | }) 50 | }) 51 | -------------------------------------------------------------------------------- /components/linear-progress/__test__/__snapshots__/LinearProgress.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`LinearProgress should render as indeterminate 1`] = ` 4 |
          5 |
          6 |
          7 |
          8 |
          9 |
          10 | `; 11 | 12 | exports[`LinearProgress should render as open 1`] = ` 13 |
          14 |
          15 |
          16 |
          17 |
          18 |
          19 | `; 20 | 21 | exports[`LinearProgress should render as reversed 1`] = ` 22 |
          23 |
          24 |
          25 |
          26 |
          27 |
          28 | `; 29 | 30 | exports[`LinearProgress should render with no prop 1`] = ` 31 |
          32 |
          33 |
          34 |
          35 |
          36 |
          37 | `; 38 | -------------------------------------------------------------------------------- /components/linear-progress/index.js: -------------------------------------------------------------------------------- 1 | import LinearProgress from './LinearProgress.vue' 2 | import './styles.scss' 3 | 4 | import { initPlugin } from '../' 5 | 6 | const plugin = { 7 | install (vm) { 8 | vm.component('m-linear-progress', LinearProgress) 9 | } 10 | } 11 | export default plugin 12 | 13 | initPlugin(plugin) 14 | -------------------------------------------------------------------------------- /components/linear-progress/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/linear-progress/mdc-linear-progress"; -------------------------------------------------------------------------------- /components/list/ListDivider.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 34 | -------------------------------------------------------------------------------- /components/list/ListGroup.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 26 | -------------------------------------------------------------------------------- /components/list/ListGroupDivider.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 33 | -------------------------------------------------------------------------------- /components/list/ListGroupSubheader.vue: -------------------------------------------------------------------------------- 1 | 27 | -------------------------------------------------------------------------------- /components/list/__test__/__snapshots__/List.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`List Divider should render as inset 1`] = ``; 4 | 5 | exports[`List Divider should render as padded 1`] = ``; 6 | 7 | exports[`List Divider should render with no prop 1`] = ``; 8 | 9 | exports[`List Group Divider should render as inset 1`] = `
          `; 10 | 11 | exports[`List Group Divider should render as padded 1`] = `
          `; 12 | 13 | exports[`List Group Divider should render with no prop 1`] = `
          `; 14 | 15 | exports[`List Group Subheader should render as h1 1`] = `

          `; 16 | 17 | exports[`List Group Subheader should render with no prop 1`] = `

          `; 18 | 19 | exports[`List Group should render with no prop 1`] = ` 20 |
          21 | 22 |
          23 | `; 24 | 25 | exports[`List Item should render as activated 1`] = ` 26 |
        • 27 | 28 |
        • 29 | `; 30 | 31 | exports[`List Item should render as disabled 1`] = ` 32 |
        • 33 | 34 |
        • 35 | `; 36 | 37 | exports[`List Item should render as selected 1`] = ` 38 |
        • 39 | 40 |
        • 41 | `; 42 | 43 | exports[`List Item should render with no prop 1`] = ` 44 |
        • 45 | 46 |
        • 47 | `; 48 | 49 | exports[`List should render as avatar 1`] = `
            `; 50 | 51 | exports[`List should render as dense 1`] = `
              `; 52 | 53 | exports[`List should render as div 1`] = `
              `; 54 | 55 | exports[`List should render as nav 1`] = ``; 56 | 57 | exports[`List should render as non interactive 1`] = `
                `; 58 | 59 | exports[`List should render as two line 1`] = `
                  `; 60 | 61 | exports[`List should render with no prop 1`] = `
                    `; 62 | -------------------------------------------------------------------------------- /components/list/index.js: -------------------------------------------------------------------------------- 1 | import List from './List.vue' 2 | import ListDivider from './ListDivider.vue' 3 | import ListGroup from './ListGroup.vue' 4 | import ListGroupDivider from './ListGroupDivider.vue' 5 | import ListGroupSubheader from './ListGroupSubheader.vue' 6 | import ListItem from './ListItem.vue' 7 | import './styles.scss' 8 | 9 | import { initPlugin } from '../' 10 | 11 | const plugin = { 12 | install (vm) { 13 | vm.component('m-list', List) 14 | vm.component('m-list-divider', ListDivider) 15 | vm.component('m-list-group', ListGroup) 16 | vm.component('m-list-group-divider', ListGroupDivider) 17 | vm.component('m-list-group-subheader', ListGroupSubheader) 18 | vm.component('m-list-item', ListItem) 19 | } 20 | } 21 | export default plugin 22 | 23 | initPlugin(plugin) 24 | -------------------------------------------------------------------------------- /components/list/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/list/mdc-list"; -------------------------------------------------------------------------------- /components/menu/MenuAnchor.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /components/menu/MenuSelectionGroup.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 37 | 38 | 41 | -------------------------------------------------------------------------------- /components/menu/__test__/Menu.spec.js: -------------------------------------------------------------------------------- 1 | import { mount } from '@vue/test-utils' 2 | import Menu from '../Menu.vue' 3 | import MenuAnchor from '../MenuAnchor.vue' 4 | import MenuSurface from '../MenuSurface' 5 | import MenuSelectionGroup from '../MenuSelectionGroup' 6 | import 'mutationobserver-shim' 7 | 8 | describe('Menu', () => { 9 | it('should mount', () => { 10 | const wrapper = mount(Menu) 11 | expect(wrapper.isVueInstance()).toBeTruthy() 12 | }) 13 | 14 | it('should render with no prop', () => { 15 | const wrapper = mount(Menu) 16 | expect(wrapper).toMatchSnapshot() 17 | expect(wrapper.classes()).toContain('mdc-menu') 18 | expect(wrapper.classes()).toContain('mdc-menu-surface') 19 | }) 20 | 21 | it('should render as fixed', () => { 22 | const wrapper = mount(Menu, { 23 | propsData: { 24 | fixed: true 25 | } 26 | }) 27 | expect(wrapper).toMatchSnapshot() 28 | }) 29 | }) 30 | 31 | describe('MenuSurface', () => { 32 | it('should mount', () => { 33 | const wrapper = mount(MenuSurface) 34 | expect(wrapper.isVueInstance()).toBeTruthy() 35 | }) 36 | 37 | it('should render with no prop', () => { 38 | const wrapper = mount(MenuSurface) 39 | expect(wrapper).toMatchSnapshot() 40 | expect(wrapper.classes()).toContain('mdc-menu-surface') 41 | }) 42 | 43 | it('should render as fixed', () => { 44 | const wrapper = mount(MenuSurface, { 45 | propsData: { 46 | fixed: true 47 | } 48 | }) 49 | expect(wrapper).toMatchSnapshot() 50 | }) 51 | }) 52 | 53 | describe('MenuAnchor', () => { 54 | it('should mount', () => { 55 | const wrapper = mount(MenuAnchor) 56 | expect(wrapper.isVueInstance()).toBeTruthy() 57 | }) 58 | 59 | it('should render with no prop', () => { 60 | const wrapper = mount(MenuAnchor) 61 | expect(wrapper).toMatchSnapshot() 62 | expect(wrapper.classes()).toContain('mdc-menu-surface--anchor') 63 | }) 64 | }) 65 | 66 | describe('MenuSelectionGroup', () => { 67 | it('should mount', () => { 68 | const wrapper = mount(MenuSelectionGroup) 69 | expect(wrapper.isVueInstance()).toBeTruthy() 70 | }) 71 | 72 | it('should render with no prop', () => { 73 | const wrapper = mount(MenuSelectionGroup) 74 | expect(wrapper).toMatchSnapshot() 75 | expect(wrapper.classes()).toContain('mdc-menu__selection-group') 76 | }) 77 | }) 78 | -------------------------------------------------------------------------------- /components/menu/__test__/__snapshots__/Menu.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Menu should render as fixed 1`] = `
                    `; 4 | 5 | exports[`Menu should render with no prop 1`] = `
                    `; 6 | 7 | exports[`MenuAnchor should render with no prop 1`] = `
                    `; 8 | 9 | exports[`MenuSelectionGroup should render with no prop 1`] = `
                      `; 10 | 11 | exports[`MenuSurface should render as fixed 1`] = `
                      `; 12 | 13 | exports[`MenuSurface should render with no prop 1`] = `
                      `; 14 | -------------------------------------------------------------------------------- /components/menu/index.js: -------------------------------------------------------------------------------- 1 | import Menu from './Menu.vue' 2 | import MenuAnchor from './MenuAnchor.vue' 3 | import MenuSurface from './MenuSurface.vue' 4 | import MenuSelectionGroup from './MenuSelectionGroup' 5 | import './styles.scss' 6 | 7 | import { initPlugin } from '../' 8 | 9 | const plugin = { 10 | install (vm) { 11 | vm.component('m-menu', Menu) 12 | vm.component('m-menu-anchor', MenuAnchor) 13 | vm.component('m-menu-surface', MenuSurface) 14 | vm.component('m-menu-selection-group', MenuSelectionGroup) 15 | } 16 | } 17 | export default plugin 18 | 19 | initPlugin(plugin) 20 | -------------------------------------------------------------------------------- /components/menu/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/menu-surface/mdc-menu-surface"; 2 | @import "@material/menu/mdc-menu"; -------------------------------------------------------------------------------- /components/notched-outline/NotchedOutline.vue: -------------------------------------------------------------------------------- 1 | 13 | 50 | -------------------------------------------------------------------------------- /components/notched-outline/README.md: -------------------------------------------------------------------------------- 1 | ## NotchedOutline 2 | 3 | ### Markup 4 | 5 | ```html 6 | 9 | Outlined 10 | 11 | 12 | ``` 13 | 14 | ### Props 15 | 16 | | Prop | Type | Default | Description | 17 | |------|------|---------|-------------| 18 | | notched | Boolean | false | open notch outline | 19 | 20 | -------------------------------------------------------------------------------- /components/notched-outline/index.js: -------------------------------------------------------------------------------- 1 | import NotchedOutline from './NotchedOutline.vue' 2 | import './styles.scss' 3 | 4 | import { initPlugin } from '../' 5 | 6 | const plugin = { 7 | install (vm) { 8 | vm.component('m-notched-outline', NotchedOutline) 9 | } 10 | } 11 | export default plugin 12 | 13 | initPlugin(plugin) 14 | -------------------------------------------------------------------------------- /components/notched-outline/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/notched-outline/mdc-notched-outline"; 2 | -------------------------------------------------------------------------------- /components/radio/README.md: -------------------------------------------------------------------------------- 1 | ## Radio 2 | 3 | ### Markup 4 | 5 | ```html 6 | 7 | 8 | 9 | ``` 10 | ### Script 11 | 12 | ```javascript 13 | data() { 14 | return { 15 | radioGroup: '' 16 | } 17 | } 18 | ``` 19 | 20 | ### Props 21 | 22 | | Prop | Type | Default | Description | 23 | |------|------|---------|-------------| 24 | | checked | Boolean | false | whether the radio is selected | 25 | | disabled | Boolean | false | disabled radio | 26 | | value | String | '' | value of radio (will be v-modeled) | 27 | | name | String | '' | radio group name | 28 | | js | Boolean | true | Whether or not to use an optional JavaScript component to enhance it with a ripple interaction effect | 29 | 30 | Non prop attributes are mapped to the inner input element. 31 | 32 | ### Reference 33 | 34 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-radio 35 | -------------------------------------------------------------------------------- /components/radio/__test__/Radio.spec.js: -------------------------------------------------------------------------------- 1 | import 'mutationobserver-shim' 2 | import { mount } from '@vue/test-utils' 3 | import Radio from '../Radio.vue' 4 | 5 | describe('Radio', () => { 6 | it('should mount', () => { 7 | const wrapper = mount(Radio) 8 | expect(wrapper.isVueInstance()).toBeTruthy() 9 | expect(wrapper.vm.$data.mdcRadio).toBeDefined() 10 | }) 11 | 12 | it('should render with no prop', () => { 13 | const wrapper = mount(Radio) 14 | expect(wrapper).toMatchSnapshot() 15 | expect(wrapper.classes()).toContain('mdc-radio') 16 | expect(wrapper.find('input').attributes('disabled')).toBeUndefined() 17 | }) 18 | 19 | it('should render as disabled', () => { 20 | const wrapper = mount(Radio, { 21 | attrs: { 22 | disabled: true 23 | } 24 | }) 25 | 26 | expect(wrapper).toMatchSnapshot() 27 | expect(wrapper.classes()).toContain('mdc-radio--disabled') 28 | expect(wrapper.find('input').attributes('disabled')).toBeDefined() 29 | }) 30 | 31 | it('should render and emit', () => { 32 | const wrapper = mount(Radio, { 33 | attrs: { 34 | value: 'val' 35 | } 36 | }) 37 | 38 | expect(wrapper).toMatchSnapshot() 39 | 40 | const radio = wrapper.find('input') 41 | radio.setChecked(true) 42 | expect(wrapper.emitted().change.length).toBe(1) 43 | expect(wrapper.emitted().change[0]).toEqual(['val']) 44 | }) 45 | }) 46 | -------------------------------------------------------------------------------- /components/radio/__test__/__snapshots__/Radio.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Radio should render and emit 1`] = ` 4 |
                      5 |
                      6 |
                      7 |
                      8 |
                      9 |
                      10 | `; 11 | 12 | exports[`Radio should render as disabled 1`] = ` 13 |
                      14 |
                      15 |
                      16 |
                      17 |
                      18 |
                      19 | `; 20 | 21 | exports[`Radio should render with no prop 1`] = ` 22 |
                      23 |
                      24 |
                      25 |
                      26 |
                      27 |
                      28 | `; 29 | -------------------------------------------------------------------------------- /components/radio/index.js: -------------------------------------------------------------------------------- 1 | import Radio from './Radio.vue' 2 | import './styles.scss' 3 | 4 | import { initPlugin } from '../' 5 | 6 | const plugin = { 7 | install (vm) { 8 | vm.component('m-radio', Radio) 9 | } 10 | } 11 | export default plugin 12 | 13 | initPlugin(plugin) 14 | -------------------------------------------------------------------------------- /components/radio/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/radio/mdc-radio"; -------------------------------------------------------------------------------- /components/ripple/README.md: -------------------------------------------------------------------------------- 1 | ## Ripple 2 | 3 | Material Components Vue provides a customized directive `v-ripple` to provide any components with ripple effect. 4 | 5 | ### Minimal Usage 6 | 7 | ```html 8 | Button 9 | ``` 10 | 11 | ### Use primary color as ripple color 12 | 13 | ```html 14 | Button 15 | ``` 16 | 17 | ### Use secondary color as ripple color 18 | 19 | ```html 20 | Button 21 | ``` 22 | 23 | ### Customized your ripple using SASS 24 | 25 | ```html 26 | 29 | 30 | 42 | ``` 43 | 44 | ### CSS-Only ripple 45 | 46 | ```html 47 | Button 48 | ``` 49 | 50 | ### Activate or deactivate using binding value 51 | 52 | 53 | ```html 54 | 55 | ``` 56 | ```js 57 | this.$refs.ripple.mdcRipple.activated() // activated 58 | this.$refs.ripple.mdcRipple.deactivated() // deactivated 59 | ``` 60 | 61 | Content below is deprecated, which means they may be removed in the future versions. 62 | 63 | ### Markup 64 | 65 | ```html 66 | 67 | Ripple 68 | 69 | ``` 70 | 71 | ### Props & methods 72 | 73 | | Prop | Type | Default | Description | 74 | |------|------|---------|-------------| 75 | | unbounded | Boolean | false | unbounded ripple | 76 | | accent | Boolean | false | ripple with secondary theme color | 77 | 78 | ### Slots 79 | 80 | | Slot | Description | 81 | |------|-------------| 82 | | default | ripple content | 83 | 84 | ### Reference 85 | 86 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-ripple 87 | -------------------------------------------------------------------------------- /components/ripple/Ripple.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 58 | -------------------------------------------------------------------------------- /components/ripple/index.js: -------------------------------------------------------------------------------- 1 | import Ripple from './Ripple.vue' 2 | import { MDCRipple } from '@material/ripple' 3 | import './styles.scss' 4 | 5 | import { initPlugin } from '../' 6 | 7 | function setupClasses (el, binding) { 8 | const mod = binding.modifiers 9 | mod.customized ? el.classList.remove('mdc-ripple-surface') : el.classList.add('mdc-ripple-surface') 10 | mod.primary ? el.classList.add('mdc-ripple-surface--primary') : el.classList.remove('mdc-ripple-surface--primary') 11 | mod.accent ? el.classList.add('mdc-ripple-surface--accent') : el.classList.remove('mdc-ripple-surface--accent') 12 | } 13 | 14 | const plugin = { 15 | install (vm) { 16 | vm.component('m-ripple', Ripple) 17 | vm.directive('ripple', { 18 | bind: function (el, binding) { 19 | setupClasses(el, binding) 20 | if (!binding.modifiers['css-only']) { 21 | const mdcRipple = MDCRipple.attachTo(el) 22 | Object.defineProperty(el, 'mdcRipple', { 23 | configurable: true, 24 | enumerable: false, 25 | value: mdcRipple, 26 | writable: false 27 | }) 28 | } 29 | }, 30 | unbind: function (el) { 31 | if (el.mdcRipple) { 32 | el.mdcRipple.destroy() 33 | } 34 | } 35 | }) 36 | } 37 | } 38 | export default plugin 39 | 40 | initPlugin(plugin) 41 | -------------------------------------------------------------------------------- /components/ripple/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/ripple/mdc-ripple"; -------------------------------------------------------------------------------- /components/select/SelectHelperText.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 65 | 66 | 69 | -------------------------------------------------------------------------------- /components/select/SelectIcon.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 82 | 83 | 86 | -------------------------------------------------------------------------------- /components/select/index.js: -------------------------------------------------------------------------------- 1 | import Select from './Select.vue' 2 | import SelectHelperText from './SelectHelperText.vue' 3 | import SelectIcon from './SelectIcon' 4 | import './styles.scss' 5 | 6 | import { initPlugin } from '../' 7 | 8 | const plugin = { 9 | install (vm) { 10 | vm.component('m-select', Select) 11 | vm.component('m-select-helper-text', SelectHelperText) 12 | vm.component('m-select-icon', SelectIcon) 13 | } 14 | } 15 | export default plugin 16 | 17 | initPlugin(plugin) 18 | -------------------------------------------------------------------------------- /components/select/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/list/mdc-list"; 2 | @import "@material/menu-surface/mdc-menu-surface"; 3 | @import "@material/menu/mdc-menu"; 4 | @import "@material/select/mdc-select"; 5 | @import "@material/notched-outline/mdc-notched-outline"; 6 | @import "@material/select/helper-text/mdc-select-helper-text"; 7 | -------------------------------------------------------------------------------- /components/shape/README.md: -------------------------------------------------------------------------------- 1 | ## Shape 2 | 3 | ### Markup 4 | 5 | ```html 6 | 10 | 13 | Button 14 | 15 | 16 | ``` 17 | 18 | ### Style 19 | 20 | ```scss 21 | @import "@material/shape/mixins"; 22 | 23 | .my-shape-container { 24 | @include mdc-shape-angled-corner(#fff, 10px); 25 | } 26 | ``` 27 | ### Props 28 | 29 | | Prop | Type | Default | Description | 30 | |------|------|---------|-------------| 31 | | topLeft | Boolean | false | top left corner will be angled | 32 | | topRight | Boolean | false | top right corner will be angled | 33 | | bottomLeft | Boolean | false | bottom left corner will be angled | 34 | | bottomRight | Boolean | false | bottom right corner will be angled | 35 | 36 | ### Slots 37 | 38 | | Slot | Description | 39 | |------|-------------| 40 | | default | unelevated component | 41 | 42 | ### Reference 43 | 44 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-shape 45 | -------------------------------------------------------------------------------- /components/shape/Shape.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 48 | -------------------------------------------------------------------------------- /components/shape/index.js: -------------------------------------------------------------------------------- 1 | import Shape from './Shape.vue' 2 | import './styles.scss' 3 | 4 | import { initPlugin } from '../' 5 | 6 | const plugin = { 7 | install (vm) { 8 | vm.component('m-shape', Shape) 9 | } 10 | } 11 | export default plugin 12 | 13 | initPlugin(plugin) 14 | -------------------------------------------------------------------------------- /components/shape/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/shape/mixins"; 2 | @import "@material/shape/functions"; -------------------------------------------------------------------------------- /components/slider/README.md: -------------------------------------------------------------------------------- 1 | ## Slider 2 | 3 | ### Markup 4 | 5 | ```html 6 | 7 | 8 | 9 | ``` 10 | 11 | ### Script 12 | 13 | ```javascript 14 | data() { 15 | return { 16 | sliderValue: 0 17 | } 18 | } 19 | ``` 20 | 21 | ### Props 22 | 23 | | Prop | Type | Default | Required | Description | 24 | |------|------|---------|----------|-------------| 25 | | displayMarkers | Boolean | - | false | whether markers should be rendered on the slider | 26 | | discrete | Boolean | - | false | discrete slider values | 27 | | value | Number | - | false | slider value, can be `v-model` | 28 | | min | Number | - | true | minimum slider value | 29 | | max | Number | - | true | maximum slider value | 30 | | step | Number | - | false | step value | 31 | | disabled | Boolean | - | false | whether the slider should be disabled | 32 | 33 | Non prop attributes are mapped to the root element. 34 | 35 | ### Events 36 | 37 | | Event | Payload | Description | 38 | |-------|---------|-------------| 39 | | input | `value` | Emitted whenever the slider value is changed by way of a user event, e.g. when a user is dragging the slider or changing the value using the arrow keys. Payload is the current value of the slider. | 40 | | change | `value` | Emitted whenever the slider value is changed and committed by way of a user event, e.g. when a user stops dragging the slider or changes the value using the arrow keys. Payload is the current value of the slider. | 41 | 42 | ### Reference 43 | 44 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-slider 45 | -------------------------------------------------------------------------------- /components/slider/__tests__/Slider.spec.js: -------------------------------------------------------------------------------- 1 | import { mount } from '@vue/test-utils' 2 | import Slider from '../Slider.vue' 3 | 4 | describe('Slider', () => { 5 | it('should mount', () => { 6 | const wrapper = mount(Slider) 7 | expect(wrapper.isVueInstance()).toBeTruthy() 8 | expect(wrapper.vm.$data.mdcSlider).toBeDefined() 9 | }) 10 | 11 | it('should render with no prop', () => { 12 | const wrapper = mount(Slider) 13 | expect(wrapper).toMatchSnapshot() 14 | expect(wrapper.classes()).toContain('mdc-slider') 15 | }) 16 | 17 | it('should render as discrete', () => { 18 | const wrapper = mount(Slider, { 19 | propsData: { 20 | discrete: true 21 | } 22 | }) 23 | expect(wrapper).toMatchSnapshot() 24 | expect(wrapper.classes()).toContain('mdc-slider--discrete') 25 | }) 26 | 27 | it('should render and display markers', () => { 28 | const wrapper = mount(Slider, { 29 | propsData: { 30 | discrete: true, 31 | displayMarkers: true 32 | } 33 | }) 34 | expect(wrapper).toMatchSnapshot() 35 | expect(wrapper.classes()).toContain('mdc-slider--display-markers') 36 | }) 37 | 38 | it('should render as disabled', () => { 39 | const wrapper = mount(Slider, { 40 | propsData: { 41 | disabled: true 42 | } 43 | }) 44 | expect(wrapper).toMatchSnapshot() 45 | }) 46 | }) 47 | -------------------------------------------------------------------------------- /components/slider/index.js: -------------------------------------------------------------------------------- 1 | import Slider from './Slider.vue' 2 | import './styles.scss' 3 | 4 | import { initPlugin } from '../' 5 | 6 | const plugin = { 7 | install (vm) { 8 | vm.component('m-slider', Slider) 9 | } 10 | } 11 | export default plugin 12 | 13 | initPlugin(plugin) 14 | -------------------------------------------------------------------------------- /components/slider/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/slider/mdc-slider"; -------------------------------------------------------------------------------- /components/snackbar/README.md: -------------------------------------------------------------------------------- 1 | ## Snackbar 2 | 3 | ### Markup 4 | 5 | ```html 6 | open 10 | 11 | ``` 12 | 13 | ### Script 14 | 15 | ```javascript 16 | data () { 17 | return { 18 | isSnackbarOpen: false 19 | } 20 | } 21 | ``` 22 | 23 | ### Props 24 | 25 | | Prop | Type | Default | Required | Description | 26 | |------|------|---------|----------|-------------| 27 | | timeoutMs | Number | 5000 | - | Sets the automatic dismiss timeout in milliseconds. Value must be between 4000 and 10000 or an error will be thrown. | 28 | | closeOnEscape | Boolean | true | - | Sets whether the snackbar closes when it is focused and the user presses the ESC key. | 29 | | labelText | String | - | true | Sets the text content of the label element. | 30 | | open | Boolean | false | - | Set the snackbar's state. Can be `v-model` | 31 | | actionButtonText | String | '' | false | Sets the text content of the action button element. | 32 | | leading | Boolean | false | - | Positions the snackbar on the leading edge of the screen (left in LTR, right in RTL) instead of centered. | 33 | | stacked | Boolean | false | - | Positions the action button/icon below the label instead of alongside it. | 34 | | hasDismiss | Boolean | false | - | Weather the snackbar has the dismiss (“X”) icon. | 35 | | dismissClass | String | 'material-icons' | false | Class for dismiss icon button. You can place class from other library, for example, Font Awesome's `fa` here. | 36 | 37 | ### Slots 38 | 39 | | Slot | Description | 40 | |------|-------------| 41 | | default | The text content of the label element. Same as the `labelText` prop. | 42 | | dismiss | Content of the dismiss icon. | 43 | 44 | ### Reference 45 | 46 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-snackbar 47 | -------------------------------------------------------------------------------- /components/snackbar/index.js: -------------------------------------------------------------------------------- 1 | import Snackbar from './Snackbar.vue' 2 | import './styles.scss' 3 | 4 | import { initPlugin } from '../' 5 | 6 | const plugin = { 7 | install (vm) { 8 | vm.component('m-snackbar', Snackbar) 9 | } 10 | } 11 | export default plugin 12 | 13 | initPlugin(plugin) 14 | -------------------------------------------------------------------------------- /components/snackbar/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/snackbar/mdc-snackbar"; 2 | @import "@material/button/mdc-button"; 3 | @import "@material/icon-button/mdc-icon-button"; 4 | 5 | -------------------------------------------------------------------------------- /components/switch/README.md: -------------------------------------------------------------------------------- 1 | ## Switch 2 | 3 | ### Markup 4 | 5 | ```html 6 | 7 | ``` 8 | 9 | ### Script 10 | 11 | ```javascript 12 | data() { 13 | return { 14 | switchValue: false 15 | } 16 | } 17 | ``` 18 | 19 | ### Props 20 | 21 | | Prop | Type | Default | Required | Description | 22 | |------|------|---------|----------|-------------| 23 | | checked | Boolean | - | false | switch state, can be `v-model` | 24 | | disabled | Boolean | - | false | whether the switch should be disabled | 25 | 26 | Non prop attributes are mapped to the inner input element. 27 | 28 | ### Reference 29 | 30 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-switch 31 | -------------------------------------------------------------------------------- /components/switch/Switch.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 74 | -------------------------------------------------------------------------------- /components/switch/__test__/Switch.spec.js: -------------------------------------------------------------------------------- 1 | import { mount } from '@vue/test-utils' 2 | import Switch from '../Switch.vue' 3 | 4 | describe('Switch', () => { 5 | it('should mount', () => { 6 | const wrapper = mount(Switch) 7 | expect(wrapper.isVueInstance()).toBeTruthy() 8 | expect(wrapper.vm.$data.mdcSwitch).toBeDefined() 9 | }) 10 | 11 | it('should render with no prop', () => { 12 | const wrapper = mount(Switch) 13 | expect(wrapper).toMatchSnapshot() 14 | expect(wrapper.classes()).toContain('mdc-switch') 15 | expect(wrapper.find('input').attributes('disabled')).toBeUndefined() 16 | }) 17 | 18 | it('should render as disabled', () => { 19 | const wrapper = mount(Switch, { 20 | propsData: { 21 | disabled: true 22 | } 23 | }) 24 | expect(wrapper).toMatchSnapshot() 25 | expect(wrapper.classes()).toContain('mdc-switch--disabled') 26 | expect(wrapper.find('input').attributes('disabled')).toBeDefined() 27 | }) 28 | 29 | it('should render as checked', () => { 30 | const wrapper = mount(Switch, { 31 | propsData: { 32 | checked: true 33 | } 34 | }) 35 | expect(wrapper).toMatchSnapshot() 36 | expect(wrapper.vm.$data.mdcSwitch.checked).toBeTruthy() 37 | expect(wrapper.find('input').element.checked).toBeTruthy() 38 | }) 39 | 40 | it('should render and emit', () => { 41 | const wrapper = mount(Switch) 42 | 43 | const input = wrapper.find('input') 44 | 45 | input.setChecked() 46 | expect(wrapper.emitted().change).toBeTruthy() 47 | expect(wrapper.vm.$data.mdcSwitch.checked).toBeTruthy() 48 | expect(wrapper.find('input').element.checked).toBeTruthy() 49 | 50 | input.setChecked(false) 51 | expect(wrapper.emitted().change).toBeTruthy() 52 | expect(wrapper.vm.$data.mdcSwitch.checked).toBeFalsy() 53 | expect(wrapper.find('input').element.checked).toBeFalsy() 54 | }) 55 | }) 56 | -------------------------------------------------------------------------------- /components/switch/__test__/__snapshots__/Switch.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Switch should render as checked 1`] = ` 4 |
                      5 |
                      6 |
                      7 |
                      8 |
                      9 |
                      10 | `; 11 | 12 | exports[`Switch should render as disabled 1`] = ` 13 |
                      14 |
                      15 |
                      16 |
                      17 |
                      18 |
                      19 | `; 20 | 21 | exports[`Switch should render with no prop 1`] = ` 22 |
                      23 |
                      24 |
                      25 |
                      26 |
                      27 |
                      28 | `; 29 | -------------------------------------------------------------------------------- /components/switch/index.js: -------------------------------------------------------------------------------- 1 | import Switch from './Switch.vue' 2 | import './styles.scss' 3 | 4 | import { initPlugin } from '../' 5 | 6 | const plugin = { 7 | install (vm) { 8 | vm.component('m-switch', Switch) 9 | } 10 | } 11 | export default plugin 12 | 13 | initPlugin(plugin) 14 | -------------------------------------------------------------------------------- /components/switch/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/switch/mdc-switch"; -------------------------------------------------------------------------------- /components/tabs/TabIndicator.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 83 | 84 | 87 | -------------------------------------------------------------------------------- /components/tabs/TabScroller.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 59 | 60 | 63 | -------------------------------------------------------------------------------- /components/tabs/index.js: -------------------------------------------------------------------------------- 1 | import Tab from './Tab.vue' 2 | import TabBar from './TabBar.vue' 3 | import TabIndicator from './TabIndicator.vue' 4 | import TabScroller from './TabScroller.vue' 5 | import './styles.scss' 6 | 7 | import { initPlugin } from '../' 8 | 9 | const plugin = { 10 | install (vm) { 11 | vm.component('m-tab', Tab) 12 | vm.component('m-tab-bar', TabBar) 13 | vm.component('m-tab-indicator', TabIndicator) 14 | vm.component('m-tab-scroller', TabScroller) 15 | } 16 | } 17 | export default plugin 18 | 19 | initPlugin(plugin) 20 | -------------------------------------------------------------------------------- /components/tabs/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/tab-bar/mdc-tab-bar"; 2 | @import "@material/tab-scroller/mdc-tab-scroller"; 3 | @import "@material/tab-indicator/mdc-tab-indicator"; 4 | @import "@material/tab/mdc-tab"; -------------------------------------------------------------------------------- /components/text-field/TextFieldCharacterCounter.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 71 | 72 | 75 | -------------------------------------------------------------------------------- /components/text-field/TextFieldHelperLine.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 18 | -------------------------------------------------------------------------------- /components/text-field/TextFieldHelperText.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 70 | -------------------------------------------------------------------------------- /components/text-field/TextFieldIcon.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 84 | -------------------------------------------------------------------------------- /components/text-field/index.js: -------------------------------------------------------------------------------- 1 | import TextField from './TextField.vue' 2 | import TextFieldHelperText from './TextFieldHelperText.vue' 3 | import TextFieldCharacterCounter from './TextFieldCharacterCounter' 4 | import TextFieldHelperLine from './TextFieldHelperLine' 5 | import './styles.scss' 6 | 7 | import { initPlugin } from '../' 8 | import TextFieldIcon from './TextFieldIcon' 9 | 10 | const plugin = { 11 | install (vm) { 12 | vm.component('m-text-field', TextField) 13 | vm.component('m-text-field-helper-text', TextFieldHelperText) 14 | vm.component('m-text-field-helper-line', TextFieldHelperLine) 15 | vm.component('m-text-field-character-counter', TextFieldCharacterCounter) 16 | vm.component('m-text-field-icon', TextFieldIcon) 17 | } 18 | } 19 | export default plugin 20 | 21 | initPlugin(plugin) 22 | -------------------------------------------------------------------------------- /components/text-field/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/textfield/mdc-text-field"; 2 | @import "@material/textfield/helper-text/mdc-text-field-helper-text"; 3 | -------------------------------------------------------------------------------- /components/theme/README.md: -------------------------------------------------------------------------------- 1 | ## Theme 2 | 3 | This component can be used for runtime theming and avoiding SASS if you don't need the flexibility. 4 | If you want to create a static customized style than you should consider using SASS - working with 5 | variables in SASS is easier and faster. 6 | 7 | All content that will be rendered in a theme component will be styled with the given custom style. 8 | This way it is possible to have several different themed components grouped together. 9 | 10 | ### Markup 11 | 12 | ```html 13 | 14 | themed content 15 | 16 | ``` 17 | ### Script 18 | 19 | ```javascript 20 | const customStyle = { 21 | --mdc-theme-primary: '#4286f4' 22 | } 23 | ``` 24 | 25 | ### Props 26 | 27 | | Prop | Type | Default | Description | 28 | |------|------|---------|-------------| 29 | | customStyles | Object | {} | customize theme variables | 30 | 31 | ### Slots 32 | 33 | | Slot | Description | 34 | |------|-------------| 35 | | default | themed content | 36 | 37 | For a complete list of all CSS custom properties have a look at the [reference](https://github.com/material-components/material-components-web/tree/master/packages/mdc-theme#css-custom-properties). 38 | 39 | ### Reference 40 | 41 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-theme 42 | -------------------------------------------------------------------------------- /components/theme/Theme.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | -------------------------------------------------------------------------------- /components/theme/index.js: -------------------------------------------------------------------------------- 1 | import Theme from './Theme.vue' 2 | import './styles.scss' 3 | 4 | import { initPlugin } from '../' 5 | 6 | const plugin = { 7 | install (vm) { 8 | vm.component('m-theme', Theme) 9 | } 10 | } 11 | export default plugin 12 | 13 | initPlugin(plugin) 14 | -------------------------------------------------------------------------------- /components/theme/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/theme/mdc-theme"; -------------------------------------------------------------------------------- /components/top-app-bar/TopAppBarFixedAdjust.vue: -------------------------------------------------------------------------------- 1 | 43 | -------------------------------------------------------------------------------- /components/top-app-bar/index.js: -------------------------------------------------------------------------------- 1 | import TopAppBar from './TopAppBar.vue' 2 | import TopAppBarFixedAdjust from './TopAppBarFixedAdjust.vue' 3 | import './styles.scss' 4 | 5 | import { initPlugin } from '../' 6 | 7 | const plugin = { 8 | install (vm) { 9 | vm.component('m-top-app-bar', TopAppBar) 10 | vm.component('m-top-app-bar-fixed-adjust', TopAppBarFixedAdjust) 11 | } 12 | } 13 | export default plugin 14 | 15 | initPlugin(plugin) 16 | -------------------------------------------------------------------------------- /components/top-app-bar/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/top-app-bar/mdc-top-app-bar"; 2 | -------------------------------------------------------------------------------- /components/typography/Body.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 28 | -------------------------------------------------------------------------------- /components/typography/Button.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /components/typography/Caption.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /components/typography/Headline.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 28 | -------------------------------------------------------------------------------- /components/typography/Overline.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /components/typography/README.md: -------------------------------------------------------------------------------- 1 | ## Typography 2 | 3 | ### Markup 4 | 5 | ```html 6 | 7 | Headline 8 | Overline 9 | Subheading 1 10 | Body 2 11 | Caption 12 | Button 13 | 14 | ``` 15 | 16 | ### Slots 17 | 18 | | Slot | Description | 19 | |------|-------------| 20 | | default | typography content | 21 | 22 | ## Body 23 | 24 | ### Props 25 | 26 | | Prop | Type | Default | Description | 27 | |------|------|---------|-------------| 28 | | level | Number | - | body level could be 1 or 2 | 29 | 30 | ### Slots 31 | 32 | | Slot | Description | 33 | |------|-------------| 34 | | default | content | 35 | 36 | ## Button 37 | 38 | ### Slots 39 | 40 | | Slot | Description | 41 | |------|-------------| 42 | | default | content | 43 | 44 | ## Caption 45 | 46 | ### Slots 47 | 48 | | Slot | Description | 49 | |------|-------------| 50 | | default | content | 51 | 52 | ## Headline 53 | 54 | ### Props 55 | 56 | | Prop | Type | Default | Description | 57 | |------|------|---------|-------------| 58 | | level | Boolean | false | headline level between 1 and 6 | 59 | 60 | ### Slots 61 | 62 | | Slot | Description | 63 | |------|-------------| 64 | | default | content | 65 | 66 | ## Subheading 67 | 68 | ### Props 69 | 70 | | Prop | Type | Default | Description | 71 | |------|------|---------|-------------| 72 | | level | Number | - | subheading level could be 1 or 2 | 73 | 74 | ### Slots 75 | 76 | | Slot | Description | 77 | |------|-------------| 78 | | default | content | 79 | 80 | ## Overline 81 | 82 | ### Slots 83 | 84 | | Slot | Description | 85 | |------|-------------| 86 | | default | content | 87 | 88 | ### Reference 89 | 90 | - https://github.com/material-components/material-components-web/tree/master/packages/mdc-toolbar 91 | -------------------------------------------------------------------------------- /components/typography/Subheading.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 28 | -------------------------------------------------------------------------------- /components/typography/Typography.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /components/typography/index.js: -------------------------------------------------------------------------------- 1 | import Body from './Body.vue' 2 | import Button from './Button.vue' 3 | import Caption from './Caption.vue' 4 | import Headline from './Headline.vue' 5 | import Overline from './Overline.vue' 6 | import Subheading from './Subheading.vue' 7 | import Typography from './Typography.vue' 8 | import './styles.scss' 9 | 10 | import { initPlugin } from '../' 11 | 12 | const plugin = { 13 | install (vm) { 14 | vm.component('m-typo-body', Body) 15 | vm.component('m-typo-button', Button) 16 | vm.component('m-typo-caption', Caption) 17 | vm.component('m-typo-headline', Headline) 18 | vm.component('m-typo-overline', Overline) 19 | vm.component('m-typo-subheading', Subheading) 20 | vm.component('m-typography', Typography) 21 | } 22 | } 23 | export default plugin 24 | 25 | initPlugin(plugin) 26 | -------------------------------------------------------------------------------- /components/typography/styles.scss: -------------------------------------------------------------------------------- 1 | @import "@material/typography/mdc-typography"; -------------------------------------------------------------------------------- /docs/.vuepress/components/ButtonDemo.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 49 | -------------------------------------------------------------------------------- /docs/.vuepress/components/CardDemo.vue: -------------------------------------------------------------------------------- 1 | 43 | 44 | 59 | 60 | 71 | -------------------------------------------------------------------------------- /docs/.vuepress/components/CardMediaDemo.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 43 | 44 | 65 | -------------------------------------------------------------------------------- /docs/.vuepress/components/CheckboxDemo.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 31 | -------------------------------------------------------------------------------- /docs/.vuepress/components/ChipsInputDemo.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 44 | -------------------------------------------------------------------------------- /docs/.vuepress/components/ComponentLayout.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | -------------------------------------------------------------------------------- /docs/.vuepress/components/ComponentProps.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 71 | 72 | 78 | -------------------------------------------------------------------------------- /docs/.vuepress/components/ComponentSection.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 32 | -------------------------------------------------------------------------------- /docs/.vuepress/components/DismissibleDrawerDemo.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 18 | -------------------------------------------------------------------------------- /docs/.vuepress/components/ElevationDemo.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 40 | 41 | -------------------------------------------------------------------------------- /docs/.vuepress/components/FabDemo.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 48 | -------------------------------------------------------------------------------- /docs/.vuepress/components/LayoutGridDemo.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 44 | 45 | 51 | -------------------------------------------------------------------------------- /docs/.vuepress/components/LinearProgressDemo.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 28 | 29 | 32 | -------------------------------------------------------------------------------- /docs/.vuepress/components/ListWithActivatedItemDemo.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 29 | 30 | 37 | -------------------------------------------------------------------------------- /docs/.vuepress/components/ListWithTrailingCheckboxDemo.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 41 | 42 | 49 | -------------------------------------------------------------------------------- /docs/.vuepress/components/ListWithTrailingRadioButtonsDemo.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 41 | 42 | 49 | -------------------------------------------------------------------------------- /docs/.vuepress/components/MenuDemo.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 62 | -------------------------------------------------------------------------------- /docs/.vuepress/components/MenuSurfaceDemo.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 54 | 55 | 61 | -------------------------------------------------------------------------------- /docs/.vuepress/components/ModalDrawerDemo.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 18 | -------------------------------------------------------------------------------- /docs/.vuepress/components/PermanentDrawerDemo.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 18 | -------------------------------------------------------------------------------- /docs/.vuepress/components/RippleDemo.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 31 | 32 | -------------------------------------------------------------------------------- /docs/.vuepress/components/SingleLineListDemo.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | 24 | -------------------------------------------------------------------------------- /docs/.vuepress/components/SliderDemo.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 33 | 34 | 37 | -------------------------------------------------------------------------------- /docs/.vuepress/components/SnackbarDemo.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 38 | 39 | 41 | -------------------------------------------------------------------------------- /docs/.vuepress/components/SwitchDemo.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 29 | 30 | 33 | -------------------------------------------------------------------------------- /docs/.vuepress/components/TabsDemo.vue: -------------------------------------------------------------------------------- 1 | 43 | 44 | 74 | 75 | 77 | -------------------------------------------------------------------------------- /docs/.vuepress/components/TopAppBarDemo.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 18 | -------------------------------------------------------------------------------- /docs/.vuepress/components/TwoLineListDemo.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 37 | 38 | 45 | -------------------------------------------------------------------------------- /docs/.vuepress/components/TwoLineWithLeadingAndTrailingIconAndDividerDemo.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 54 | 55 | 62 | -------------------------------------------------------------------------------- /docs/.vuepress/components/ripple/MyButton.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | -------------------------------------------------------------------------------- /docs/.vuepress/config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const nodeModules = path.resolve('node_modules/') 3 | 4 | module.exports = { 5 | title: 'Material Components Vue', 6 | description: 'Material Design components for Vue.js', 7 | base: '/material-components-vue/', 8 | head: [ 9 | ['link', { rel: 'icon', href: '/logo.png'}] 10 | ], 11 | themeConfig: { 12 | repo: 'matsp/material-components-vue', 13 | nav: [ 14 | { text: 'Guide', link: '/guide/' }, 15 | { text: 'Components', link: '/components/' } 16 | ] 17 | }, 18 | scss: { 19 | sassOptions: { 20 | includePaths: [nodeModules] 21 | } 22 | }, 23 | port: 9090 24 | } 25 | -------------------------------------------------------------------------------- /docs/.vuepress/enhanceApp.js: -------------------------------------------------------------------------------- 1 | import './styles.scss' 2 | 3 | import AutoInit from '../../components/auto-init' 4 | import Button from '../../components/button' 5 | import Icon from '../../components/icon' 6 | import Radio from '../../components/radio' 7 | import FormField from '../../components/form-field' 8 | import Checkbox from '../../components/checkbox' 9 | import Select from '../../components/select' 10 | import Card from '../../components/card' 11 | import Chips from '../../components/chips' 12 | import TextField from '../../components/text-field' 13 | import FloatingLabel from '../../components/floating-label' 14 | import LineRipple from '../../components/line-ripple' 15 | import NotchedOutline from '../../components/notched-outline' 16 | import List from '../../components/list' 17 | import Menu from '../../components/menu' 18 | import LayoutGrid from '../../components/layout-grid' 19 | import Typography from '../../components/typography' 20 | import Fab from '../../components/fab' 21 | import IconButton from '../../components/icon-button' 22 | import Dialog from '../../components/dialog' 23 | import Drawer from '../../components/drawer' 24 | import TopAppBar from '../../components/top-app-bar' 25 | import ImageList from '../../components/image-list' 26 | import Slider from '../../components/slider' 27 | import Switch from '../../components/switch' 28 | import LinearProgress from '../../components/linear-progress' 29 | import Snackbar from '../../components/snackbar' 30 | import Tabs from '../../components/tabs' 31 | import Ripple from '../../components/ripple' 32 | import Elevation from '../../components/elevation' 33 | 34 | export default ({ 35 | Vue, // the version of Vue being used in the VuePress app 36 | options, // the options for the root Vue instance 37 | router, // the router instance for the app 38 | siteData // site metadata 39 | }) => { 40 | Vue.use(AutoInit) 41 | Vue.use(Button) 42 | Vue.use(Icon) 43 | Vue.use(Radio) 44 | Vue.use(Checkbox) 45 | Vue.use(FormField) 46 | Vue.use(Select) 47 | Vue.use(Card) 48 | Vue.use(Chips) 49 | Vue.use(TextField) 50 | Vue.use(FloatingLabel) 51 | Vue.use(LineRipple) 52 | Vue.use(NotchedOutline) 53 | Vue.use(LayoutGrid) 54 | Vue.use(Typography) 55 | Vue.use(Fab) 56 | Vue.use(IconButton) 57 | Vue.use(List) 58 | Vue.use(Menu) 59 | Vue.use(Dialog) 60 | Vue.use(Drawer) 61 | Vue.use(TopAppBar) 62 | Vue.use(ImageList) 63 | Vue.use(Slider) 64 | Vue.use(Switch) 65 | Vue.use(LinearProgress) 66 | Vue.use(Snackbar) 67 | Vue.use(Tabs) 68 | Vue.use(Ripple) 69 | Vue.use(Elevation) 70 | } 71 | -------------------------------------------------------------------------------- /docs/.vuepress/override.styl: -------------------------------------------------------------------------------- 1 | // showing default values 2 | // $accentColor = #3eaf7c 3 | $accentColor = #5e35b1 4 | $textColor = #2c3e50 5 | $borderColor = #eaecef 6 | $codeBgColor = #282c34 -------------------------------------------------------------------------------- /docs/.vuepress/public/assets/fonts/materialicons-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matsp/material-components-vue/eca355adb4fd3379cbe7b96ce5ebb015a4ead865/docs/.vuepress/public/assets/fonts/materialicons-regular.woff -------------------------------------------------------------------------------- /docs/.vuepress/public/assets/fonts/materialicons-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matsp/material-components-vue/eca355adb4fd3379cbe7b96ce5ebb015a4ead865/docs/.vuepress/public/assets/fonts/materialicons-regular.woff2 -------------------------------------------------------------------------------- /docs/.vuepress/public/assets/fonts/roboto-300.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matsp/material-components-vue/eca355adb4fd3379cbe7b96ce5ebb015a4ead865/docs/.vuepress/public/assets/fonts/roboto-300.woff -------------------------------------------------------------------------------- /docs/.vuepress/public/assets/fonts/roboto-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matsp/material-components-vue/eca355adb4fd3379cbe7b96ce5ebb015a4ead865/docs/.vuepress/public/assets/fonts/roboto-300.woff2 -------------------------------------------------------------------------------- /docs/.vuepress/public/assets/fonts/roboto-500.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matsp/material-components-vue/eca355adb4fd3379cbe7b96ce5ebb015a4ead865/docs/.vuepress/public/assets/fonts/roboto-500.woff -------------------------------------------------------------------------------- /docs/.vuepress/public/assets/fonts/roboto-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matsp/material-components-vue/eca355adb4fd3379cbe7b96ce5ebb015a4ead865/docs/.vuepress/public/assets/fonts/roboto-500.woff2 -------------------------------------------------------------------------------- /docs/.vuepress/public/assets/fonts/roboto-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matsp/material-components-vue/eca355adb4fd3379cbe7b96ce5ebb015a4ead865/docs/.vuepress/public/assets/fonts/roboto-regular.woff -------------------------------------------------------------------------------- /docs/.vuepress/public/assets/fonts/roboto-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matsp/material-components-vue/eca355adb4fd3379cbe7b96ce5ebb015a4ead865/docs/.vuepress/public/assets/fonts/roboto-regular.woff2 -------------------------------------------------------------------------------- /docs/.vuepress/public/assets/images/cat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matsp/material-components-vue/eca355adb4fd3379cbe7b96ce5ebb015a4ead865/docs/.vuepress/public/assets/images/cat.jpg -------------------------------------------------------------------------------- /docs/.vuepress/public/assets/images/cat_169.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matsp/material-components-vue/eca355adb4fd3379cbe7b96ce5ebb015a4ead865/docs/.vuepress/public/assets/images/cat_169.jpg -------------------------------------------------------------------------------- /docs/.vuepress/public/assets/images/mcv-hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matsp/material-components-vue/eca355adb4fd3379cbe7b96ce5ebb015a4ead865/docs/.vuepress/public/assets/images/mcv-hero.png -------------------------------------------------------------------------------- /docs/.vuepress/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matsp/material-components-vue/eca355adb4fd3379cbe7b96ce5ebb015a4ead865/docs/.vuepress/public/logo.png -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | home: true 3 | heroImage: /assets/images/mcv-hero.png 4 | actionText: Get Started → 5 | actionLink: /guide/ 6 | features: 7 | - title: Material Design Specs 8 | details: This library wraps the official Google mdc-web components which implement the Material Design specs. 9 | - title: Easy API 10 | details: Simple and small as possible component APIs, without reinventing HTML. 11 | - title: Decoupled Components 12 | details: Any component can be imported and used on it's own. 13 | footer: MIT Licensed | Copyright © 2017-present Mats Pfeiffer 14 | --- 15 | 16 | ## Quick Start 17 | 18 | ```bash 19 | npm install --save material-components-vue 20 | 21 | # or with yarn 22 | yarn add material-components-vue 23 | ``` 24 | 25 | ```vue 26 | 29 | 30 | 33 | 34 | 37 | ``` 38 | 39 | -------------------------------------------------------------------------------- /docs/components/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar: auto 3 | --- 4 | 5 | # Components 6 | 7 | ::: warning 8 | This projects includes all components that are available at the official mdc-web repository! 9 | 10 | The demonstration in this page is a work in progress.. 11 | ::: 12 | 13 | ## Button 14 | 15 | 16 | 17 | ## Card 18 | 19 | 20 | 21 | ### Media Card 22 | 23 | 24 | 25 | ## Checkbox 26 | 27 | 28 | 29 | ## Chips 30 | 31 | ### Chips 32 | 33 | 34 | 35 | ## Elevation 36 | 37 | 38 | 39 | ## Fab 40 | 41 | 42 | 43 | 46 | 47 | ## Icon Button 48 | 49 | 50 | 51 | ## Menu 52 | 53 | 54 | 55 | ## Menu Surface 56 | 57 | 58 | 59 | ## Data Table (using Auto Init) 60 | 61 | 62 | 63 | ## Dialog 64 | 65 | 66 | 67 | ## Drawer 68 | 69 | ### [Permanent Drawer](permanentDrawer.html) 70 | 71 | 72 | 73 | ### [Dismissible Drawer](dismissibleDrawer.html) 74 | 75 | 76 | 77 | ### [Modal Drawer](modalDrawer.html) 78 | 79 | 80 | 81 | ## Image List 82 | 83 | 84 | 85 | ## Select Menus 86 | 87 | 88 | 89 | ## Slider 90 | 91 | 92 | 93 | ## Switch 94 | 95 | 96 | 97 | ## Text Field 98 | 99 | 100 | 101 | ## Layout Grid 102 | 103 | 104 | 105 | ## Linear Progress 106 | 107 | 108 | 109 | ## List 110 | 111 | ### Single-line List 112 | 113 | 114 | 115 | ### Two-line list 116 | 117 | 118 | 119 | ### List with activated item 120 | 121 | 122 | 123 | ### Two-Line with Leading and Trailing Icon and Divider 124 | 125 | 126 | 127 | ### List with Trailing Radio Buttons 128 | 129 | 130 | 131 | ### List with Trailing Checkbox 132 | 133 | 134 | 135 | ## Ripple 136 | 137 | 138 | 139 | ## Snackbar 140 | 141 | 142 | 143 | ## Tabs 144 | 145 | 146 | 147 | ## [Top App Bar](top-app-bar.html) 148 | 149 | 150 | -------------------------------------------------------------------------------- /docs/components/dismissibleDrawer.md: -------------------------------------------------------------------------------- 1 | --- 2 | navbar: false 3 | sidebar: false 4 | pageClass: custom-page-class 5 | layout: drawer-DismissibleDrawerDemo 6 | --- 7 | -------------------------------------------------------------------------------- /docs/components/modalDrawer.md: -------------------------------------------------------------------------------- 1 | --- 2 | navbar: false 3 | sidebar: false 4 | pageClass: custom-page-class 5 | layout: drawer-ModalDrawerDemo 6 | --- 7 | -------------------------------------------------------------------------------- /docs/components/permanentDrawer.md: -------------------------------------------------------------------------------- 1 | --- 2 | navbar: false 3 | sidebar: false 4 | pageClass: custom-page-class 5 | layout: drawer-PermanentDrawerDemo 6 | --- 7 | -------------------------------------------------------------------------------- /docs/components/top-app-bar.md: -------------------------------------------------------------------------------- 1 | --- 2 | navbar: false 3 | sidebar: false 4 | pageClass: custom-page-class 5 | layout: topAppBar-Demo 6 | --- 7 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const merge = require('webpack-merge') 3 | const common = require('./webpack.config.common') 4 | 5 | const root = path.join(__dirname) 6 | 7 | module.exports = merge(common, { 8 | mode: 'development', 9 | target: 'web', 10 | output: { 11 | path: path.resolve(root + '/dist'), 12 | filename: '[name]/index.js', 13 | libraryTarget: 'umd' 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /webpack.config.min.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const UglifyJSPlugin = require('uglifyjs-webpack-plugin') 3 | const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin') 4 | const merge = require('webpack-merge') 5 | const common = require('./webpack.config.common') 6 | 7 | const root = path.join(__dirname) 8 | 9 | module.exports = merge(common, { 10 | mode: 'production', 11 | target: 'web', 12 | output: { 13 | path: path.resolve(root + '/dist'), 14 | filename: '[name]/[name].min.js', 15 | libraryTarget: 'umd' 16 | }, 17 | plugins: [ 18 | new UglifyJSPlugin({ 19 | uglifyOptions: { 20 | ecma: 5 21 | }, 22 | cache: true, 23 | parallel: true, 24 | extractComments: true 25 | }), 26 | new OptimizeCssAssetsPlugin() 27 | ] 28 | }) 29 | --------------------------------------------------------------------------------