From f1d7f830bf2f12dab288c46a5fc2919d5d608110 Mon Sep 17 00:00:00 2001 From: Andrew Date: Sat, 24 Jan 2015 14:24:16 -0700 Subject: [PATCH] feat(input): make input placeholder attr work Closes #1279. --- .../input/demoBasicUsage/index.html | 2 +- src/components/input/input-theme.scss | 3 +- src/components/input/input.js | 38 ++++++++++++++----- src/components/input/input.scss | 26 ++++++++++++- 4 files changed, 57 insertions(+), 12 deletions(-) diff --git a/src/components/input/demoBasicUsage/index.html b/src/components/input/demoBasicUsage/index.html index 2782126693c..c4666e8cb49 100644 --- a/src/components/input/demoBasicUsage/index.html +++ b/src/components/input/demoBasicUsage/index.html @@ -22,7 +22,7 @@
- + diff --git a/src/components/input/input-theme.scss b/src/components/input/input-theme.scss index 5ee6a416aef..b345a0afe20 100644 --- a/src/components/input/input-theme.scss +++ b/src/components/input/input-theme.scss @@ -6,7 +6,8 @@ md-input-container.md-THEME_NAME-theme { text-shadow: '{{foreground-shadow}}'; } - label { + label, + .md-placeholder { text-shadow: '{{foreground-shadow}}'; color: '{{foreground-3}}'; } diff --git a/src/components/input/input.js b/src/components/input/input.js index 6b0c46bc052..583a52b59c4 100644 --- a/src/components/input/input.js +++ b/src/components/input/input.js @@ -12,7 +12,8 @@ angular.module('material.components.input', [ .directive('label', labelDirective) .directive('input', inputTextareaDirective) .directive('textarea', inputTextareaDirective) - .directive('mdMaxlength', mdMaxlengthDirective); + .directive('mdMaxlength', mdMaxlengthDirective) + .directive('placeholder', placeholderDirective); /** * @ngdoc directive @@ -42,7 +43,7 @@ angular.module('material.components.input', [ * * */ -function mdInputContainerDirective($mdTheming) { +function mdInputContainerDirective($mdTheming, $animate, $mdUtil) { return { restrict: 'E', link: postLink, @@ -52,18 +53,18 @@ function mdInputContainerDirective($mdTheming) { function postLink(scope, element, attr) { $mdTheming(element); } - function ContainerCtrl($scope, $element, $mdUtil) { + function ContainerCtrl($scope, $element) { var self = this; self.element = $element; self.setFocused = function(isFocused) { - $element.toggleClass('md-input-focused', !!isFocused); + $animate[isFocused ? 'addClass' : 'removeClass']($element, 'md-input-focused'); }; self.setHasValue = function(hasValue) { - $element.toggleClass('md-input-has-value', !!hasValue); + $animate[hasValue ? 'addClass' : 'removeClass']($element, 'md-input-has-value'); }; self.setInvalid = function(isInvalid) { - $element.toggleClass('md-input-invalid', !!isInvalid); + $animate[isInvalid ? 'addClass' : 'removeClass']($element, 'md-input-invalid'); }; $scope.$watch(function() { @@ -207,11 +208,15 @@ function inputTextareaDirective($mdUtil, $window, $compile, $animate) { element .on('input', inputCheckValue) .on('focus', function(ev) { - containerCtrl.setFocused(true); + scope.$evalAsync(function() { + containerCtrl.setFocused(true); + }); }) .on('blur', function(ev) { - containerCtrl.setFocused(false); - inputCheckValue(); + scope.$evalAsync(function() { + containerCtrl.setFocused(false); + inputCheckValue(); + }); }); scope.$on('$destroy', function() { @@ -313,4 +318,19 @@ function mdMaxlengthDirective($animate) { } } +function placeholderDirective() { + return { + restrict: 'A', + require: '^mdInputContainer', + link: postLink + }; + + function postLink(scope, element, attr, inputContainer) { + var placeholderText = attr.placeholder; + element.removeAttr('placeholder'); + + inputContainer.element.append('
' + placeholderText + '
'); + } +} + })(); diff --git a/src/components/input/input.scss b/src/components/input/input.scss index b321959acb0..d13b83500ae 100644 --- a/src/components/input/input.scss +++ b/src/components/input/input.scss @@ -5,6 +5,8 @@ $input-label-default-scale: 1.0 !default; $input-label-float-offset: 4px !default; $input-label-float-scale: 0.75 !default; +$input-placeholder-offset: $input-label-default-offset !default; + $input-border-width-default: 1px !default; $input-border-width-focused: 2px !default; $input-line-height: 26px !default; @@ -44,7 +46,8 @@ md-input-container { overflow: hidden; } - label { + label, + .md-placeholder { order: 1; pointer-events: none; -webkit-font-smoothing: antialiased; @@ -54,6 +57,24 @@ md-input-container { transform-origin: left top; transition: transform $swift-ease-out-timing-function 0.25s; } + .md-placeholder { + position: absolute; + top: 0; + opacity: 0; + transition-property: opacity, transform; + transform: translate3d(0, $input-placeholder-offset + $baseline-grid, 0); + } + &.md-input-focused:not(.md-input-has-value) { + .md-placeholder { + opacity: 1; + transform: translate3d(0, $input-placeholder-offset, 0); + } + } + &.md-input-has-value-remove-active, + &.md-input-focused { + transition: none; + transition-delay: none; + } /* * The .md-input class is added to the input/textarea @@ -117,6 +138,9 @@ md-input-container { transform: translate3d(0,$input-label-float-offset,0) scale($input-label-float-scale); } } + &.md-input-has-value .md-placeholder { + transition: none; + } // Use wide border in error state or in focused state &.md-input-focused .md-input,