From 2594f170cf11cd359a71e8fa0124b90988d2bab5 Mon Sep 17 00:00:00 2001 From: gerard Date: Thu, 28 Jun 2018 15:54:54 +0200 Subject: [PATCH] =?UTF-8?q?Bug=20#137=20Refactorizaci=C3=B3n=20Textfield?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/src/components/textfield/style.scss | 157 +++++++++++++----- .../src/components/textfield/textfield.html | 69 +++++--- .../src/components/textfield/textfield.js | 60 +++++-- .../components/textfield/textfield.spec.js | 28 +++- 4 files changed, 227 insertions(+), 87 deletions(-) diff --git a/client/core/src/components/textfield/style.scss b/client/core/src/components/textfield/style.scss index 181ad8d8b..10609c55c 100644 --- a/client/core/src/components/textfield/style.scss +++ b/client/core/src/components/textfield/style.scss @@ -1,45 +1,124 @@ +@import "colors"; vn-textfield { - .mdl-chip__action { - position: absolute; - width: auto; - top: 0px; - right: -6px; - margin: 21px 0px; - background: white; - opacity: 1; - z-index: 1; - color: #aaa; - } - .mdl-textfield { - width: 100%; - } - .mdl-textfield__error { - visibility: visible; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - width: 100%; - } - .mdl-textfield.invalid { - .mdl-textfield__input { - border-color: #d50000; - box-shadow: none; + margin: 20px 0!important; + display: block; + + .leftIcons, .rightIcons, .suffix{ + display: inline-flex; + color: $secondary-font-color; + & .material-icons{ + font-size: 20px!important } - .mdl-textfield__label::after { + } + .leftIcons{ + margin-right: 3px; + } + .container{ + width: 100%; + position: relative; + padding-bottom: 2px; + } + .textField{ + width: 100%; + display: inline-flex; + position: relative; + padding: 4px 0; + } + .infix { + position: relative; + display: block; + flex: auto; + width: 100%; + min-width: 0; + } + i.pointer { + visibility: hidden; + } + i.visible { + visibility: visible; + } + label { + position: absolute; + bottom: 2px; + pointer-events: none; + color: $secondary-font-color; + transition-duration: .2s; + transition-timing-function: cubic-bezier(.4,0,.2,1); + } + input { + outline: none; + border: none; + font-family: "Helvetica","Arial",sans-serif; + display: block; + font-size: 16px; + width: 100%; + background: 0 0; + color: inherit; + + &[type=number] { + -moz-appearance: textfield; + &::-webkit-outer-spin-button, + &::-webkit-inner-spin-button{ + -webkit-appearance: none; + margin: 0; + } + } + &:invalid { + box-shadow:none; + } + } + .underline{ + position: absolute; + bottom: 0; + height: 1px; + content: ' '; + pointer-events: none; + width: 100%; + background-color: rgba(0,0,0,.12); + } + .selected.underline{ + background-color: rgb(255,152,0); + height: 2px; + left: 50%; + width: 0px!important; + transition-duration: 0.2s; + transition-timing-function: cubic-bezier(.4,0,.2,1); + } + &.not-empty { + & label { + bottom: 24px; + color: $main-01; + font-size: 12px; + } + } + div.selected{ + &.container{ + border-bottom: 0px; + } + & label { + bottom: 24px; + color: $main-01; + font-size: 12px; + } + & .selected.underline{ + left: 0; + width: 100%!important; + } + } + & > div.container > div.textField > div.infix.invalid{ + @extend div.selected; + + & > span.mdl-textfield__error{ + visibility: visible; + margin-top: 9px; + } + & > label{ + color: #d50000; + } + } + .infix.invalid + .underline { + &{ background-color: #d50000; } } - .mdl-textfield--floating-label.invalid .mdl-textfield__label { - color: #d50000; - font-size: 12px; - top: 4px; - } - .material-icons { - font-size: 18px; - float: right; - margin-right: 5px; - } - .material-icons:hover { - color: rgba(0,0,0, .87); - } } \ No newline at end of file diff --git a/client/core/src/components/textfield/textfield.html b/client/core/src/components/textfield/textfield.html index fe69149a3..edd341b9c 100644 --- a/client/core/src/components/textfield/textfield.html +++ b/client/core/src/components/textfield/textfield.html @@ -1,29 +1,46 @@ -
- -
- - info_outline - - - clear - + ng-mouseleave="$ctrl.hasMouseIn = false" + style="display: inline-flex" +> +
+
+
+ +
+ + + +
+
+
+
+ + clear + + + info_outline + +
+
-
diff --git a/client/core/src/components/textfield/textfield.js b/client/core/src/components/textfield/textfield.js index 56fc23955..fb86e2309 100644 --- a/client/core/src/components/textfield/textfield.js +++ b/client/core/src/components/textfield/textfield.js @@ -3,45 +3,73 @@ import Input from '../../lib/input'; import './style.scss'; export default class Textfield extends Input { - constructor($element, $scope, $attrs, vnTemplate) { + constructor($element, $scope, $attrs, vnTemplate, $transclude) { super($element, $scope); vnTemplate.normalizeInputAttrs($attrs); this._value = null; - this.type = $attrs.type || 'text'; + this.type = $attrs.type; this.showActions = false; this.hasInfo = Boolean($attrs.info); this.info = $attrs.info || null; this.hasFocus = false; this.hasMouseIn = false; - componentHandler.upgradeElement($element[0].firstChild); + + if ($transclude) { + $transclude($scope.$parent, tClone => { + this.leftIcons = tClone[0]; + }, null, 'leftIcons'); + $transclude($scope.$parent, tClone => { + this.rightIcons = tClone[0]; + }, null, 'rightIcons'); + } } - get value() { - return this._value; + set onChange(value) { + this.input.addEventListener('change', value); + } + + set leftIcons(value) { + for (let i = 0; i < value.children.length; i++) { + this.element.querySelector('.leftIcons').appendChild(value.children[i]); + } + } + set rightIcons(value) { + for (let i = 0; i < value.children.length; i++) { + this.element.querySelector('.rightIcons').appendChild(value.children[i]); + } } set value(value) { this._value = (value === undefined || value === '') ? null : value; this.input.value = this._value; - this.hasValue = Boolean(this._value); - this.mdlUpdate(); - } + this.hasValue = this._value !== null; + if (this.hasValue) this.element.classList.add('not-empty'); + else this.element.classList.remove('not-empty'); + } + get value() { + return this._value; + } + set type(value) { + this._type = value || 'text'; + } + get type() { + return this._type; + } set vnTabIndex(value) { this.input.tabindex = value; } - clear() { this.value = null; this.input.focus(); } - mdlUpdate() { - let mdlElement = this.element.firstChild.MaterialTextfield; - if (mdlElement) mdlElement.updateClasses_(); - } } -Textfield.$inject = ['$element', '$scope', '$attrs', 'vnTemplate']; +Textfield.$inject = ['$element', '$scope', '$attrs', 'vnTemplate', '$transclude']; ngModule.component('vnTextfield', { template: require('./textfield.html'), + transclude: { + leftIcons: '?tLeftIcons', + rightIcons: '?tRightIcons' + }, controller: Textfield, bindings: { value: '=model', @@ -51,6 +79,8 @@ ngModule.component('vnTextfield', { readonly: ' { $attrs = {}; $timeout = _$timeout_; $element = angular.element('
'); - controller = $componentController('vnTextfield', {$scope, $element, $attrs, $timeout}); + controller = $componentController('vnTextfield', {$scope, $element, $attrs, $timeout, $transclude: null}); })); describe('value() setter', () => { - it(`should set _value, input.value and hasValue properties to null, '' and false then call mdlUpdate()`, () => { - spyOn(controller, 'mdlUpdate'); + it(`should set _value, input.value and hasValue properties to null, '' and false`, () => { let testValue = ''; controller.value = testValue; expect(controller._value).toEqual(null); expect(controller.input.value).toEqual(testValue); expect(controller.hasValue).toEqual(Boolean(testValue)); - expect(controller.mdlUpdate).toHaveBeenCalledWith(); }); - it(`should set _value, input.value and hasValue propertiest to test, test and true then call mdlUpdate()`, () => { - spyOn(controller, 'mdlUpdate'); + it(`should set _value, input.value and hasValue propertiest to test, test and true`, () => { let testValue = 'test'; controller.value = testValue; expect(controller._value).toEqual(testValue); expect(controller.input.value).toEqual(testValue); expect(controller.hasValue).toEqual(Boolean(testValue)); - expect(controller.mdlUpdate).toHaveBeenCalledWith(); + }); + }); + + describe('type() setter', () => { + it(`should set _type to 'text' if theres not given value`, () => { + controller.type = null; + + expect(controller._type).toEqual('text'); + }); + }); + + describe('clear()', () => { + it(`should set value property to null and call focus`, () => { + spyOn(controller.input, 'focus'); + controller.clear(); + + expect(controller.value).toEqual(null); + expect(controller.input.focus).toHaveBeenCalledWith(); }); }); });