Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit 0c87f08

Browse files
EladBezalelThomasBurleson
authored andcommitted
fix(input): smart support of icons
- Fixed single icon on the right - Added smart classes applying, now the directive will automatically add md-icon-left/right according the icon placement (after/before the input) fixes #6348 Closes #6720
1 parent 5b42709 commit 0c87f08

File tree

4 files changed

+124
-37
lines changed

4 files changed

+124
-37
lines changed

src/components/input/demoIcons/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
</md-input-container>
2222

2323
<md-input-container md-no-float class="md-block">
24-
<md-icon md-svg-src="img/icons/ic_place_24px.svg" style="display:inline-block;"></md-icon>
2524
<input ng-model="user.address" type="text" placeholder="Address" >
25+
<md-icon md-svg-src="img/icons/ic_place_24px.svg" style="display:inline-block;"></md-icon>
2626
</md-input-container>
2727

2828
<md-input-container class="md-icon-float md-icon-right md-block">

src/components/input/input.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,24 @@ function mdInputContainerDirective($mdTheming, $parse) {
6060
controller: ContainerCtrl
6161
};
6262

63-
function postLink(scope, element, attr) {
63+
function postLink(scope, element) {
6464
$mdTheming(element);
65-
if (element.find('md-icon').length) element.addClass('md-has-icon');
65+
66+
var iconElements = element.find('md-icon');
67+
var icons = iconElements.length ? iconElements : element[0].getElementsByClassName('md-icon');
68+
69+
// Incase there's one icon we want to identify where the icon is (right or left) and apply the related class
70+
if (icons.length == 1) {
71+
var next = icons[0].nextElementSibling;
72+
var previous = icons[0].previousElementSibling;
73+
74+
element.addClass(next && next.tagName === 'INPUT' ? 'md-icon-left' :
75+
previous && previous.tagName === 'INPUT' ? 'md-icon-right' : '');
76+
}
77+
// In case there are two icons we apply both icon classes
78+
else if (icons.length == 2) {
79+
element.addClass('md-icon-left md-icon-right');
80+
}
6681
}
6782

6883
function ContainerCtrl($scope, $element, $attrs, $animate) {
@@ -244,7 +259,8 @@ function inputTextareaDirective($mdUtil, $window, $mdAria) {
244259

245260
// Add an error spacer div after our input to provide space for the char counter and any ng-messages
246261
var errorsSpacer = angular.element('<div class="md-errors-spacer">');
247-
element.after(errorsSpacer);
262+
// element.after appending the div before the icon (if exist) which cause a problem with calculating which class to apply
263+
element.parent().append(errorsSpacer);
248264

249265
if (!containerCtrl.label) {
250266
$mdAria.expect(element, 'aria-label', element.attr('placeholder'));

src/components/input/input.scss

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,6 @@ md-input-container {
9393
@include rtl(right, auto, 0);
9494
}
9595

96-
// icon offset should have higher priority as normal label
97-
&.md-has-icon {
98-
@include rtl(padding-left, $icon-offset, 0);
99-
@include rtl(padding-right, 0, $icon-offset);
100-
> label {
101-
@include rtl(left, $icon-offset, auto);
102-
@include rtl(right, auto, $icon-offset);
103-
}
104-
}
105-
10696
label:not(.md-no-float):not(.md-container-ignore),
10797
.md-placeholder {
10898
order: 1;
@@ -301,46 +291,59 @@ md-input-container {
301291
margin-bottom: -1px; // Shift downward so dotted line is positioned the same as other bottom borders
302292
}
303293
}
304-
}
305294

306-
md-input-container.md-icon-float {
295+
&.md-icon-float {
307296

308-
transition: margin-top 0.5s $swift-ease-out-timing-function;
297+
transition: margin-top 0.5s $swift-ease-out-timing-function;
309298

310-
> label {
311-
pointer-events: none;
312-
position: absolute;
313-
}
299+
> label {
300+
pointer-events: none;
301+
position: absolute;
302+
}
314303

315-
> md-icon {
316-
top: 2px;
317-
@include rtl(left, 2px, auto);
318-
@include rtl(right, auto, 2px);
319-
}
304+
> md-icon {
305+
top: 2px;
306+
@include rtl(left, 2px, auto);
307+
@include rtl(right, auto, 2px);
308+
}
320309

321-
&.md-input-focused,
322-
&.md-input-has-value {
310+
&.md-input-focused,
311+
&.md-input-has-value {
323312

324-
label {
325-
transform: translate3d(0, $input-label-float-offset, 0) scale($input-label-float-scale);
326-
transition: transform $swift-ease-out-timing-function 0.5s;
313+
label {
314+
transform: translate3d(0, $input-label-float-offset, 0) scale($input-label-float-scale);
315+
transition: transform $swift-ease-out-timing-function 0.5s;
316+
}
327317
}
318+
328319
}
329320

330-
}
321+
// icon offset should have higher priority as normal label
322+
&.md-icon-left {
323+
@include rtl(padding-left, $icon-offset, 0);
324+
@include rtl(padding-right, 0, $icon-offset);
325+
> label {
326+
@include rtl(left, $icon-offset, auto);
327+
@include rtl(right, auto, $icon-offset);
328+
}
329+
}
331330

332-
md-input-container.md-icon-right {
333-
@include rtl(padding-right, $icon-offset, $icon-offset);
334-
@include rtl(padding-left, $icon-offset, $icon-offset);
331+
&.md-icon-right {
332+
@include rtl(padding-left, 0, $icon-offset);
333+
@include rtl(padding-right, $icon-offset, 0);
335334

336-
.md-errors-spacer {
337-
+ md-icon {
335+
> md-icon:last-of-type {
338336
margin: 0;
339337

340338
@include rtl(right, 2px, auto);
341339
@include rtl(left, auto, 2px);
342340
}
343341
}
342+
343+
&.md-icon-left.md-icon-right {
344+
padding-left: $icon-offset;
345+
padding-right: $icon-offset;
346+
}
344347
}
345348

346349
@media screen and (-ms-high-contrast: active) {

src/components/input/input.spec.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,4 +458,72 @@ describe('md-input-container directive', function() {
458458
expect(textarea.offsetHeight).toBeGreaterThan(oldHeight);
459459
});
460460
});
461+
462+
describe('icons', function () {
463+
it('should add md-icon-left class when md-icon is before the input', function () {
464+
var el = compile(
465+
'<md-input-container>' +
466+
' <md-icon></md-icon>' +
467+
' <input ng-model="foo">' +
468+
'</md-input-container>'
469+
);
470+
471+
expect(el.hasClass('md-icon-left')).toBeTruthy();
472+
473+
});
474+
475+
it('should add md-icon-left class when .md-icon is before the input', function () {
476+
var el = compile(
477+
'<md-input-container>' +
478+
' <i class="md-icon"></i>' +
479+
' <input ng-model="foo">' +
480+
'</md-input-container>'
481+
);
482+
expect(el.hasClass('md-icon-left')).toBeTruthy();
483+
});
484+
485+
it('should add md-icon-right class when md-icon is after the input', function () {
486+
var el = compile(
487+
'<md-input-container>' +
488+
' <input ng-model="foo">' +
489+
' <md-icon></md-icon>' +
490+
'</md-input-container>'
491+
);
492+
493+
expect(el.hasClass('md-icon-right')).toBeTruthy();
494+
495+
});
496+
497+
it('should add md-icon-right class when .md-icon is after the input', function () {
498+
var el = compile(
499+
'<md-input-container>' +
500+
' <input ng-model="foo">' +
501+
' <i class="md-icon"></i>' +
502+
'</md-input-container>'
503+
);
504+
expect(el.hasClass('md-icon-right')).toBeTruthy();
505+
});
506+
507+
it('should add md-icon-left and md-icon-right classes when md-icons are before and after the input', function () {
508+
var el = compile(
509+
'<md-input-container>' +
510+
' <md-icon></md-icon>' +
511+
' <input ng-model="foo">' +
512+
' <md-icon></md-icon>' +
513+
'</md-input-container>'
514+
);
515+
expect(el.hasClass('md-icon-left md-icon-right')).toBeTruthy();
516+
});
517+
518+
it('should add md-icon-left and md-icon-right classes when .md-icons are before and after the input', function () {
519+
var el = compile(
520+
'<md-input-container>' +
521+
' <i class="md-icon"></i>' +
522+
' <input ng-model="foo">' +
523+
' <i class="md-icon"></i>' +
524+
'</md-input-container>'
525+
);
526+
expect(el.hasClass('md-icon-left md-icon-right')).toBeTruthy();
527+
});
528+
});
461529
});

0 commit comments

Comments
 (0)