mirror of
https://github.com/Hopiu/vue-material.git
synced 2026-05-16 19:21:07 +00:00
Start creation of selects
This commit is contained in:
parent
49ff33eebd
commit
563e81279f
12 changed files with 289 additions and 122 deletions
1
TODO.md
1
TODO.md
|
|
@ -10,6 +10,7 @@ Later this should become issues with milestones
|
|||
* Dialogs
|
||||
* Cards
|
||||
* Tabs
|
||||
* Sticky subheader
|
||||
* Image loaders
|
||||
* Swipe to refresh
|
||||
* Autocomplete
|
||||
|
|
|
|||
|
|
@ -37,15 +37,16 @@
|
|||
<md-list-item v-link="button">Button</md-list-item>
|
||||
<md-list-item v-link="button-toggle">Button Toggle</md-list-item>
|
||||
<md-list-item v-link="checkbox">Checkbox</md-list-item>
|
||||
<md-list-item v-link="radio">Radio</md-list-item>
|
||||
<md-list-item v-link="switch">Switch</md-list-item>
|
||||
<md-list-item v-link="divider">Divider</md-list-item>
|
||||
<md-list-item v-link="icon">Icon</md-list-item>
|
||||
<md-list-item v-link="input">Input</md-list-item>
|
||||
<md-list-item v-link="list">List</md-list-item>
|
||||
<md-list-item v-link="radio">Radio</md-list-item>
|
||||
<md-list-item v-link="ripple">Ripple</md-list-item>
|
||||
<md-list-item v-link="select">Select</md-list-item>
|
||||
<md-list-item v-link="sidenav">Sidenav</md-list-item>
|
||||
<md-list-item v-link="subheader">Subheader</md-list-item>
|
||||
<md-list-item v-link="switch">Switch</md-list-item>
|
||||
<md-list-item v-link="theme">Theme</md-list-item>
|
||||
<md-list-item v-link="toolbar">Toolbar</md-list-item>
|
||||
<md-list-item v-link="tooltip">Tooltip</md-list-item>
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
twoWay: true
|
||||
},
|
||||
name: String,
|
||||
value: String,
|
||||
id: String,
|
||||
disabled: Boolean
|
||||
},
|
||||
|
|
|
|||
|
|
@ -84,109 +84,119 @@ $input-size: 32px;
|
|||
}
|
||||
}
|
||||
|
||||
.md-input-placeholder {
|
||||
label {
|
||||
pointer-events: auto;
|
||||
top: 10px;
|
||||
opacity: 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
input,
|
||||
textarea {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.md-input-focused,
|
||||
.md-has-value {
|
||||
label {
|
||||
pointer-events: auto;
|
||||
top: 0;
|
||||
opacity: 1;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
input,
|
||||
textarea {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.md-has-value {
|
||||
input,
|
||||
textarea {
|
||||
color: rgba(#000, .87);
|
||||
}
|
||||
}
|
||||
|
||||
.md-input-inline {
|
||||
label {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&.md-input-focused {
|
||||
.md-input-container {
|
||||
&.md-input-placeholder {
|
||||
label {
|
||||
top: 23px;
|
||||
pointer-events: auto;
|
||||
top: 10px;
|
||||
opacity: 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
input,
|
||||
textarea {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&.md-input-focused,
|
||||
&.md-has-value {
|
||||
label {
|
||||
pointer-events: auto;
|
||||
top: 0;
|
||||
opacity: 1;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
input,
|
||||
textarea {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&.md-has-value {
|
||||
label {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.md-input-disabled {
|
||||
&:after {
|
||||
background: bottom left repeat-x;
|
||||
background-image: linear-gradient(to right, rgba(#000, .38) 0%, rgba(#000, .38) 33%, transparent 0%);
|
||||
background-size: 4px 1px;
|
||||
}
|
||||
|
||||
label,
|
||||
input,
|
||||
textarea {
|
||||
color: rgba(#000, .38);
|
||||
}
|
||||
}
|
||||
|
||||
.md-has-password {
|
||||
&.md-input-focused .md-toggle-password {
|
||||
color: rgba(#000, .54);
|
||||
}
|
||||
|
||||
.md-toggle-password {
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: -2px;
|
||||
color: rgba(#000, .38);
|
||||
|
||||
.md-ink-ripple {
|
||||
input,
|
||||
textarea {
|
||||
color: rgba(#000, .87);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.md-input-invalid {
|
||||
.md-error {
|
||||
opacity: 1;
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.md-input-required {
|
||||
label:after {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 0;
|
||||
transform: translateX(calc(100% + 2px));
|
||||
content: "*";
|
||||
font-size: 12px;
|
||||
line-height: 1em;
|
||||
vertical-align: top;
|
||||
&.md-input-inline {
|
||||
label {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&.md-input-focused {
|
||||
label {
|
||||
top: 23px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&.md-has-value {
|
||||
label {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.md-input-disabled {
|
||||
&:after {
|
||||
background: bottom left repeat-x;
|
||||
background-image: linear-gradient(to right, rgba(#000, .38) 0%, rgba(#000, .38) 33%, transparent 0%);
|
||||
background-size: 4px 1px;
|
||||
}
|
||||
|
||||
label,
|
||||
input,
|
||||
textarea {
|
||||
color: rgba(#000, .38);
|
||||
}
|
||||
}
|
||||
|
||||
&.md-has-password {
|
||||
&.md-input-focused .md-toggle-password {
|
||||
color: rgba(#000, .54);
|
||||
}
|
||||
|
||||
.md-toggle-password {
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: -2px;
|
||||
color: rgba(#000, .38);
|
||||
|
||||
.md-ink-ripple {
|
||||
color: rgba(#000, .87);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.md-input-invalid {
|
||||
.md-error {
|
||||
opacity: 1;
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
&.md-input-required {
|
||||
label:after {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 0;
|
||||
transform: translateX(calc(100% + 2px));
|
||||
content: "*";
|
||||
font-size: 12px;
|
||||
line-height: 1em;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
&.md-has-select {
|
||||
&:hover {
|
||||
label {
|
||||
color: rgba(#000, .87);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,9 +13,6 @@
|
|||
<style lang="scss" src="./mdInputContainer.scss"></style>
|
||||
|
||||
<script>
|
||||
let inlineClass = 'md-input-inline';
|
||||
let hasPasswordClass = 'md-has-password';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
mdInline: Boolean,
|
||||
|
|
@ -24,12 +21,11 @@
|
|||
},
|
||||
computed: {
|
||||
classes() {
|
||||
let cssClasses = [];
|
||||
|
||||
this.mdInline && cssClasses.push(inlineClass);
|
||||
this.mdHasPassword && cssClasses.push(hasPasswordClass);
|
||||
|
||||
return cssClasses.join(' ');
|
||||
return {
|
||||
'md-input-inline': this.mdInline,
|
||||
'md-has-password': this.mdHasPassword,
|
||||
'md-has-select': this.mdHasSelect
|
||||
};
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
|
@ -38,6 +34,7 @@
|
|||
inputType: false,
|
||||
showPassword: false,
|
||||
enableCounter: false,
|
||||
mdHasSelect: false,
|
||||
counterLength: 0,
|
||||
inputLength: 0
|
||||
};
|
||||
|
|
@ -60,15 +57,19 @@
|
|||
}
|
||||
},
|
||||
ready() {
|
||||
this.input = this.$el.querySelector('input') || this.$el.querySelector('textarea');
|
||||
this.input = this.$el.querySelector('input') || this.$el.querySelector('textarea') || this.$el.querySelector('select');
|
||||
|
||||
if (!this.input) {
|
||||
this.$destroy();
|
||||
|
||||
throw new Error('Missing input inside md-input-container');
|
||||
throw new Error('Missing input/select/textarea inside md-input-container');
|
||||
}
|
||||
|
||||
this.inputType = this.input.type;
|
||||
|
||||
if (this.$el.querySelector('select')) {
|
||||
this.mdHasSelect = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
8
src/components/mdSelect/index.js
Normal file
8
src/components/mdSelect/index.js
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import mdSelect from './mdSelect.vue';
|
||||
import mdSelectTheme from './mdSelect.theme';
|
||||
|
||||
export default function install(Vue) {
|
||||
Vue.component('md-select', Vue.extend(mdSelect));
|
||||
|
||||
window.VueMaterial.styles.push(mdSelectTheme);
|
||||
}
|
||||
31
src/components/mdSelect/mdSelect.scss
Normal file
31
src/components/mdSelect/mdSelect.scss
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
@import '../../core/variables.scss';
|
||||
|
||||
.md-select {
|
||||
min-width: 128px;
|
||||
|
||||
&:hover {
|
||||
&:after {
|
||||
color: rgba(#000, .87);
|
||||
}
|
||||
}
|
||||
|
||||
&:after {
|
||||
margin-top: 9px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0;
|
||||
transform: translateY(-50%) scaleY(0.45) scaleX(0.85);
|
||||
transition: $swift-linear;
|
||||
color: rgba(#000, .54);
|
||||
content: "\25BC";
|
||||
}
|
||||
|
||||
select {
|
||||
position: absolute;
|
||||
left: -999em;
|
||||
}
|
||||
|
||||
.md-select-menu {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
6
src/components/mdSelect/mdSelect.theme
Normal file
6
src/components/mdSelect/mdSelect.theme
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
.THEME_NAME {
|
||||
.md-select,
|
||||
&.md-select {
|
||||
|
||||
}
|
||||
}
|
||||
46
src/components/mdSelect/mdSelect.vue
Normal file
46
src/components/mdSelect/mdSelect.vue
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<template>
|
||||
<div class="md-select" :class="classes">
|
||||
<div class="md-select-value">
|
||||
<select v-model="model" :name="name" :id="id" :disabled="disabled" :value="value">
|
||||
<option v-for="option in selectedOptions" :value="option.value">{{ options.text }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="md-select-menu">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" src="./mdSelect.scss"></style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
model: {
|
||||
type: [String, Array, Boolean],
|
||||
required: true,
|
||||
twoWay: true
|
||||
},
|
||||
value: String,
|
||||
name: String,
|
||||
id: String,
|
||||
disabled: Boolean
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedOptions: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
classes() {
|
||||
return {
|
||||
'md-disabled': this.disabled
|
||||
};
|
||||
}
|
||||
},
|
||||
ready() {
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
55
src/docs/pages/Select.vue
Normal file
55
src/docs/pages/Select.vue
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<template>
|
||||
<section>
|
||||
<h2 class="title">Select</h2>
|
||||
|
||||
<div>
|
||||
<md-input-container>
|
||||
<label for="movies">Movies</label>
|
||||
<md-select :model.sync="movies" name="movies" id="movies">
|
||||
<md-option value="Fight Club">Fight Club</md-option>
|
||||
<md-option value="Godfather">Godfather</md-option>
|
||||
<md-option value="Pulp Fiction">Pulp Fiction</md-option>
|
||||
<md-option value="Scarface">Scarface</md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
|
||||
<md-input-container>
|
||||
<label for="countries">Countries</label>
|
||||
<md-select :model.sync="countries" name="countries" id="countries">
|
||||
<md-option value="Australia">Australia</md-option>
|
||||
<md-option value="Brazil">Brazil</md-option>
|
||||
<md-option value="Japan">Japan</md-option>
|
||||
<md-option value="United States">United States</md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
section {
|
||||
margin: 24px;
|
||||
}
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.md-input-container + .md-input-container {
|
||||
margin-left: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
movies: 'Pulp Fiction',
|
||||
countries: null
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -4,15 +4,16 @@ import BottomBar from './pages/BottomBar';
|
|||
import Buttons from './pages/Buttons';
|
||||
import ButtonToggle from './pages/ButtonToggle';
|
||||
import Checkbox from './pages/Checkbox';
|
||||
import Radio from './pages/Radio';
|
||||
import Switch from './pages/Switch';
|
||||
import Divider from './pages/Divider';
|
||||
import Icon from './pages/Icon';
|
||||
import Input from './pages/Input';
|
||||
import Ripple from './pages/Ripple';
|
||||
import List from './pages/List';
|
||||
import Radio from './pages/Radio';
|
||||
import Ripple from './pages/Ripple';
|
||||
import Select from './pages/Select';
|
||||
import Sidenav from './pages/Sidenav';
|
||||
import Subheader from './pages/Subheader';
|
||||
import Switch from './pages/Switch';
|
||||
import Theme from './pages/Theme';
|
||||
import Toolbar from './pages/Toolbar';
|
||||
import Tooltip from './pages/Tooltip';
|
||||
|
|
@ -75,6 +76,10 @@ const routes = {
|
|||
name: 'sidenav',
|
||||
component: Sidenav
|
||||
},
|
||||
'/select': {
|
||||
name: 'select',
|
||||
component: Select
|
||||
},
|
||||
'/subheader': {
|
||||
name: 'subheader',
|
||||
component: Subheader
|
||||
|
|
|
|||
|
|
@ -1,22 +1,23 @@
|
|||
import './core/core';
|
||||
import MdTheme from './components/mdTheme';
|
||||
import MdInkRipple from './components/mdInkRipple';
|
||||
import MdAvatar from './components/mdAvatar';
|
||||
import MdBottomBar from './components/mdBottomBar';
|
||||
import MdButton from './components/mdButton';
|
||||
import MdButtonToggle from './components/mdButtonToggle';
|
||||
import MdCheckbox from './components/mdCheckbox';
|
||||
import mdRadio from './components/mdRadio';
|
||||
import mdSwitch from './components/mdSwitch';
|
||||
import MdDivider from './components/mdDivider';
|
||||
import MdIcon from './components/mdIcon';
|
||||
import MdInkRipple from './components/mdInkRipple';
|
||||
import MdInputContainer from './components/mdInputContainer';
|
||||
import MdBottomBar from './components/mdBottomBar';
|
||||
import MdToolbar from './components/mdToolbar';
|
||||
import MdTooltip from './components/mdTooltip';
|
||||
import MdList from './components/mdList';
|
||||
import mdRadio from './components/mdRadio';
|
||||
import MdSelect from './components/mdSelect';
|
||||
import MdSidenav from './components/mdSidenav';
|
||||
import MdSubheader from './components/mdSubheader';
|
||||
import MdAvatar from './components/mdAvatar';
|
||||
import MdList from './components/mdList';
|
||||
import mdSwitch from './components/mdSwitch';
|
||||
import MdToolbar from './components/mdToolbar';
|
||||
import MdTooltip from './components/mdTooltip';
|
||||
import MdWhiteframe from './components/mdWhiteframe';
|
||||
import MdTheme from './components/mdTheme';
|
||||
|
||||
let options = {
|
||||
MdAvatar,
|
||||
|
|
@ -24,15 +25,16 @@ let options = {
|
|||
MdButton,
|
||||
MdButtonToggle,
|
||||
MdCheckbox,
|
||||
mdRadio,
|
||||
mdSwitch,
|
||||
MdDivider,
|
||||
MdIcon,
|
||||
MdInputContainer,
|
||||
MdInkRipple,
|
||||
MdInputContainer,
|
||||
MdList,
|
||||
mdRadio,
|
||||
MdSelect,
|
||||
MdSidenav,
|
||||
MdSubheader,
|
||||
mdSwitch,
|
||||
MdToolbar,
|
||||
MdTooltip,
|
||||
MdWhiteframe,
|
||||
|
|
|
|||
Loading…
Reference in a new issue