diff --git a/docs/src/App.vue b/docs/src/App.vue index 5e87f18..a41d3c8 100644 --- a/docs/src/App.vue +++ b/docs/src/App.vue @@ -71,6 +71,10 @@ Dialog + + File + + Icon diff --git a/docs/src/pages/components/File.vue b/docs/src/pages/components/File.vue new file mode 100644 index 0000000..b47bf9a --- /dev/null +++ b/docs/src/pages/components/File.vue @@ -0,0 +1,122 @@ + + + diff --git a/docs/src/routes.js b/docs/src/routes.js index 95d7a8d..cd2c4c4 100644 --- a/docs/src/routes.js +++ b/docs/src/routes.js @@ -14,6 +14,7 @@ const Card = (resolve) => require(['./pages/components/Card'], resolve); const Checkbox = (resolve) => require(['./pages/components/Checkbox'], resolve); const Chips = (resolve) => require(['./pages/components/Chips'], resolve); const Dialog = (resolve) => require(['./pages/components/Dialog'], resolve); +const File = (resolve) => require(['./pages/components/File'], resolve); const Icon = (resolve) => require(['./pages/components/Icon'], resolve); const ImageLoader = (resolve) => require(['./pages/components/ImageLoader'], resolve); const InkRipple = (resolve) => require(['./pages/components/InkRipple'], resolve); @@ -110,6 +111,11 @@ const components = [ name: 'components:dialog', component: Dialog }, + { + path: '/components/file', + name: 'components:file', + component: File + }, { path: '/components/icon', name: 'components:icon', diff --git a/src/components/mdFile/index.js b/src/components/mdFile/index.js new file mode 100644 index 0000000..422b3d1 --- /dev/null +++ b/src/components/mdFile/index.js @@ -0,0 +1,8 @@ +import mdFile from './mdFile.vue'; +import mdFileTheme from './mdFile.theme'; + +export default function install(Vue) { + Vue.component('md-file', Vue.extend(mdFile)); + + Vue.material.styles.push(mdFileTheme); +} diff --git a/src/components/mdFile/mdFile.scss b/src/components/mdFile/mdFile.scss new file mode 100644 index 0000000..93308c4 --- /dev/null +++ b/src/components/mdFile/mdFile.scss @@ -0,0 +1,21 @@ +@import '../../core/stylesheets/variables.scss'; + +.md-file { + display: flex; + flex: 1; + + input[type="file"] { + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + border: 0; + } + + .md-icon { + cursor: pointer; + } +} diff --git a/src/components/mdFile/mdFile.theme b/src/components/mdFile/mdFile.theme new file mode 100644 index 0000000..0347dad --- /dev/null +++ b/src/components/mdFile/mdFile.theme @@ -0,0 +1,5 @@ +.THEME_NAME { + &.md-file { + + } +} diff --git a/src/components/mdFile/mdFile.vue b/src/components/mdFile/mdFile.vue new file mode 100644 index 0000000..e96642c --- /dev/null +++ b/src/components/mdFile/mdFile.vue @@ -0,0 +1,100 @@ + + + + + diff --git a/src/components/mdInputContainer/mdInputContainer.scss b/src/components/mdInputContainer/mdInputContainer.scss index 291ae66..7727557 100644 --- a/src/components/mdInputContainer/mdInputContainer.scss +++ b/src/components/mdInputContainer/mdInputContainer.scss @@ -7,6 +7,7 @@ $input-size: 32px; min-height: 48px; margin: 4px 0 24px; padding-top: 16px; + display: flex; position: relative; &:after { @@ -38,6 +39,7 @@ $input-size: 32px; height: $input-size; padding: 0; display: block; + flex: 1; border: none; background: none; transition: $swift-ease-out; @@ -57,6 +59,15 @@ $input-size: 32px; text-shadow: none; -webkit-text-fill-color: initial; } + + ~ .md-icon { + margin-left: 12px; + + &:after { + right: 0; + left: auto; + } + } } textarea { @@ -67,22 +78,51 @@ $input-size: 32px; line-height: 1.3em; } - .md-error { - height: 20px; - display: block !important; - position: absolute; - opacity: 0; - transform: translate3d(0, -8px, 0); - transition: $swift-ease-in; - font-size: 12px; - } - + .md-error, .md-count { height: 20px; position: absolute; - right: 0; + top: 50px; font-size: 12px; } + + .md-error { + display: block !important; + opacity: 0; + transform: translate3d(0, -8px, 0); + transition: $swift-ease-in; + } + + .md-count { + right: 0; + } + + .md-icon { + color: rgba(#000, .54); + transition: $swift-ease-out; + + &:after { + width: 36px; + height: 2px; + position: absolute; + left: 0; + bottom: 0; + z-index: 2; + content: ""; + } + + ~ { + label { + left: 36px; + } + + .md-input, + .md-textarea, + .md-file { + margin-left: 12px; + } + } + } } .md-input-container { diff --git a/src/components/mdInputContainer/mdInputContainer.theme b/src/components/mdInputContainer/mdInputContainer.theme index 6f95fb1..9c29f7a 100644 --- a/src/components/mdInputContainer/mdInputContainer.theme +++ b/src/components/mdInputContainer/mdInputContainer.theme @@ -6,10 +6,11 @@ } label, + input, + textarea, .md-error, .md-count, - input, - textarea { + .md-icon { color: #{'WARN-COLOR'}; } } @@ -39,9 +40,26 @@ -webkit-text-fill-color: transparent; } - label { + label, + .md-icon { color: #{'PRIMARY-COLOR'}; } } + + &.md-input-disabled { + label, + input, + textarea, + .md-error, + .md-count, + .md-icon, + ::-webkit-input-placeholder { + color: #{'BACKGROUND-CONTRAST-0.38'}; + } + } + + .md-icon:after { + background: #{'BACKGROUND-COLOR'}; + } } } diff --git a/src/components/mdInputContainer/mdInputContainer.vue b/src/components/mdInputContainer/mdInputContainer.vue index 6795883..927c9a4 100644 --- a/src/components/mdInputContainer/mdInputContainer.vue +++ b/src/components/mdInputContainer/mdInputContainer.vue @@ -30,6 +30,7 @@ enableCounter: false, hasSelect: false, hasPlaceholder: false, + hasFile: false, isDisabled: false, isRequired: false, isFocused: false, @@ -50,6 +51,7 @@ 'md-input-inline': this.mdInline, 'md-has-password': this.mdHasPassword, 'md-has-select': this.hasSelect, + 'md-has-file': this.hasFile, 'md-has-value': this.hasValue, 'md-input-placeholder': this.hasPlaceholder, 'md-input-disabled': this.isDisabled, @@ -80,7 +82,7 @@ } }, mounted() { - this.input = this.$el.querySelectorAll('input, textarea, select')[0]; + this.input = this.$el.querySelectorAll('input, textarea, select, .md-file')[0]; if (!this.input) { this.$destroy(); diff --git a/src/index.js b/src/index.js index 99f21e7..0c9286d 100644 --- a/src/index.js +++ b/src/index.js @@ -9,6 +9,7 @@ import MdCheckbox from './components/mdCheckbox'; import MdChips from './components/mdChips'; import MdDialog from './components/mdDialog'; import MdDivider from './components/mdDivider'; +import MdFile from './components/mdFile'; import MdIcon from './components/mdIcon'; import MdImage from './components/mdImage'; import MdInputContainer from './components/mdInputContainer'; @@ -40,6 +41,7 @@ const options = { MdChips, MdDialog, MdDivider, + MdFile, MdIcon, MdImage, MdInputContainer,