Skip to content

Commit

Permalink
fix(select): aligned select underline, placeholder and text with input
Browse files Browse the repository at this point in the history
- added ellipsis to select placeholder
- aligned floating placeholder with input
- support font-size

fixes #2124
  • Loading branch information
EladBezalel committed Apr 19, 2017
1 parent 8d0cd04 commit 12c910e
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 129 deletions.
19 changes: 19 additions & 0 deletions src/demo-app/baseline/baseline-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,22 @@ <h1>
</h1>
</md-card-content>
</md-card>

<md-card class="demo-card demo-basic">
<md-toolbar color="primary">Inputs</md-toolbar>
<md-card-content>
<md-input-container>
<input mdInput placeholder="Input" value="Text Input">
</md-input-container>
<md-select placeholder="Select">
<md-option>1</md-option>
<md-option>2</md-option>
<md-option>3</md-option>
</md-select>
<md-select>
<md-option>1</md-option>
<md-option>2</md-option>
<md-option>3</md-option>
</md-select>
</md-card-content>
</md-card>
39 changes: 39 additions & 0 deletions src/lib/core/style/_input-common.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// These styles are used by input-style components
// including md-input-container and md-select

@import './variables';

$mat-input-wrapper-spacing: 1em !default;
$mat-input-floating-placeholder-scale-factor: 0.75 !default;
$mat-input-hint-min-space: 10px !default;

// Applies a floating placeholder above the input itself.
@mixin mat-input-placeholder-floating($translateY) {
display: block;
transform: translateY($translateY) scale($mat-input-floating-placeholder-scale-factor);
width: 100% / $mat-input-floating-placeholder-scale-factor;
}

@mixin mat-input-base {
display: inline-block;
position: relative;
font-family: $mat-font-family;
line-height: normal;
outline: none;
vertical-align: middle;

// To avoid problems with text-align.
text-align: left;

[dir='rtl'] & {
text-align: right;
}
}

// Global wrapper. We need to apply margin to the element for spacing, but
// cannot apply it to the host element directly.
.mat-input-wrapper {
margin: $mat-input-wrapper-spacing 0;
// Account for the underline which has 4px of margin + 2px of border.
padding-bottom: 6px;
}
45 changes: 8 additions & 37 deletions src/lib/input/input-container.scss
Original file line number Diff line number Diff line change
@@ -1,35 +1,16 @@
@import '../core/style/variables';
@import '../core/style/vendor-prefixes';
@import '../core/style/form-common';


$mat-input-floating-placeholder-scale-factor: 0.75 !default;
$mat-input-wrapper-spacing: 1em !default;
$mat-input-hint-min-space: 10px !default;
@import '../core/style/input-common';
@import '../core/style/list-common';

// Gradient for showing the dashed line when the input is disabled.
$mat-input-underline-disabled-background-image:
linear-gradient(to right, rgba(0, 0, 0, 0.26) 0%, rgba(0, 0, 0, 0.26) 33%, transparent 0%);

// Applies a floating placeholder above the input itself.
@mixin mat-input-placeholder-floating {
display: block;
transform: translateY(-1.35em) scale($mat-input-floating-placeholder-scale-factor);
width: 100% / $mat-input-floating-placeholder-scale-factor;
}
$mat-input-placeholder-float-translate: -1.35em;

.mat-input-container {
display: inline-block;
position: relative;
font-family: $mat-font-family;
line-height: normal;

// To avoid problems with text-align.
text-align: left;

[dir='rtl'] & {
text-align: right;
}
@include mat-input-base();

// Allow icons in a prefix/suffix/hint/etc to adapt to the correct size.
& .mat-icon {
Expand All @@ -40,14 +21,6 @@ $mat-input-underline-disabled-background-image:
}
}

// Global wrapper. We need to apply margin to the element for spacing, but
// cannot apply it to the host element directly.
.mat-input-wrapper {
margin: $mat-input-wrapper-spacing 0;
// Account for the underline which has 4px of margin + 2px of border.
padding-bottom: 6px;
}

// We use a table layout to baseline align the prefix and suffix classes.
// The underline is outside of it so it can cover all of the elements under
// this table.
Expand All @@ -56,7 +29,6 @@ $mat-input-underline-disabled-background-image:
.mat-input-table {
display: inline-table;
flex-flow: column;
vertical-align: bottom;
width: 100%;

& > * {
Expand Down Expand Up @@ -109,7 +81,7 @@ $mat-input-underline-disabled-background-image:
// classes take over to fulfill this behaviour.
// Assumes the autofill is non-empty.
&:-webkit-autofill + .mat-input-placeholder-wrapper .mat-float {
@include mat-input-placeholder-floating;
@include mat-input-placeholder-floating($mat-input-placeholder-float-translate);
transition: none;
}

Expand Down Expand Up @@ -138,9 +110,8 @@ $mat-input-underline-disabled-background-image:
// Put ellipsis text overflow.
width: 100%;
display: none;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;

@include mat-truncate-line();

transform: translateY(0);
transform-origin: bottom left;
Expand All @@ -155,7 +126,7 @@ $mat-input-underline-disabled-background-image:

// Show the placeholder above the input when it's not empty, or focused.
&.mat-float:not(.mat-empty), .mat-focused &.mat-float {
@include mat-input-placeholder-floating;
@include mat-input-placeholder-floating($mat-input-placeholder-float-translate);
}

[dir='rtl'] & {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/select/_select-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
}

.mat-select-underline {
background-color: mat-color($foreground, divider);
border-color: mat-color($foreground, divider);

.mat-select:focus:not(.mat-select-disabled) & {
background-color: mat-color($primary);
Expand Down
10 changes: 4 additions & 6 deletions src/lib/select/select-animations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,12 @@ import {
*/
export const transformPlaceholder: AnimationTriggerMetadata = trigger('transformPlaceholder', [
state('floating-ltr', style({
top: '-22px',
left: '-2px',
transform: `scale(0.75)`
transform: `translateY(-1.05em) scale(0.75)`
})),
state('floating-rtl', style({
top: '-22px',
left: '2px',
transform: `scale(0.75)`
left: 'auto',
right: '0',
transform: `translateY(-1.05em) scale(0.75)`
})),
transition('* => *', animate(`400ms cubic-bezier(0.25, 0.8, 0.25, 1)`))
]);
Expand Down
18 changes: 11 additions & 7 deletions src/lib/select/select.html
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
<div class="mat-select-trigger" cdk-overlay-origin (click)="toggle()" #origin="cdkOverlayOrigin" #trigger>
<span
<div
class="mat-select-placeholder"
[class.mat-floating-placeholder]="_selectionModel.hasValue()"
[@transformPlaceholder]="_getPlaceholderAnimationState()"
[style.visibility]="_getPlaceholderVisibility()"
[style.width.px]="_selectedValueWidth"> {{ placeholder }} </span>
<span class="mat-select-value" *ngIf="_selectionModel.hasValue()">
<span class="mat-select-value-text">{{ triggerValue }}</span>
</span>
[style.visibility]="_getPlaceholderVisibility()">
<span>{{placeholder}}</span>
</div>
<div class="mat-select-value-wrapper" >
<span class="mat-select-value" *ngIf="_selectionModel.hasValue()">
{{triggerValue}}
</span>
<span class="mat-select-filler" aria-hidden="true">&nbsp;</span>

<span class="mat-select-arrow"></span>
<span class="mat-select-arrow"></span>
</div>
<span class="mat-select-underline"></span>
</div>

Expand Down
63 changes: 20 additions & 43 deletions src/lib/select/select.scss
Original file line number Diff line number Diff line change
@@ -1,32 +1,28 @@
@import '../core/style/menu-common';
@import '../core/style/list-common';
@import '../core/style/form-common';
@import '../core/style/input-common';
@import '../core/style/variables';
@import '../core/style/vendor-prefixes';
@import '../core/a11y/a11y';

$mat-select-trigger-height: 30px !default;
$mat-select-trigger-min-width: 112px !default;
$mat-select-arrow-size: 5px !default;
$mat-select-arrow-margin: 4px !default;
$mat-select-panel-max-height: 256px !default;
$mat-select-trigger-font-size: 16px !default;

.mat-select {
display: inline-block;
outline: none;
font-family: $mat-font-family;
@include mat-input-base();
}

.mat-select-trigger {
@extend .mat-input-wrapper;
display: flex;
align-items: center;
height: $mat-select-trigger-height;
min-width: $mat-select-trigger-min-width;
cursor: pointer;
position: relative;
box-sizing: border-box;
font-size: $mat-select-trigger-font-size;

[aria-disabled='true'] & {
@include user-select(none);
Expand All @@ -40,6 +36,8 @@ $mat-select-trigger-font-size: 16px !default;
left: 0;
right: 0;
height: 1px;
border-top-width: 1px;
border-top-style: solid;

[aria-disabled='true'] & {
@include mat-control-disabled-underline();
Expand All @@ -49,29 +47,23 @@ $mat-select-trigger-font-size: 16px !default;
}

.mat-select-placeholder {
position: relative;
padding: 0 2px;
position: absolute;
transform-origin: left top;
flex-grow: 1;
top: 0;

// These values are duplicated from animation code in order to
// allow placeholders to sometimes float without animating,
// for example when the value is set programmatically.
// TODO(kara): Change when animations API supports skipping animation.
&.mat-floating-placeholder {
top: -22px;
left: -2px;
text-align: left;
transform: scale(0.75);
@include mat-input-placeholder-floating(-1.05em);
}

[dir='rtl'] & {
transform-origin: right top;

&.mat-floating-placeholder {
left: 2px;
text-align: right;
}
transform-origin: bottom right;
left: auto;
right: 0;
}

// TODO: Double-check accessibility of this style
Expand All @@ -80,35 +72,20 @@ $mat-select-trigger-font-size: 16px !default;
}
}

.mat-select-value {
position: absolute;
max-width: calc(100% - #{($mat-select-arrow-size + $mat-select-arrow-margin) * 2});
flex-grow: 1;

// Firefox and some versions of IE incorrectly keep absolutely
// positioned children of flex containers in the flex flow when calculating
// position. This has been fixed for Firefox 52, slated for early 2017.
// Bug report: https://bugzilla.mozilla.org/show_bug.cgi?id=874718
//
// In the meantime, we must adjust the position to fit the top, left, and bottom edge of the
// containing trigger element. In doing so, we can use align-items: center to allow the text to
// correctly position itself in the middle of the container.
top: 0;
left: 0;
bottom: 0;

.mat-select-value-wrapper {
display: flex;
align-items: center;

[dir='rtl'] & {
left: auto;
right: 0;
}
width: 100%;
justify-content: space-between;
}

.mat-select-value-text {
.mat-select-value, .mat-select-placeholder {
@include mat-truncate-line();
line-height: $mat-select-trigger-height;
}

.mat-select-filler {
width: 0;
visibility: hidden;
}

.mat-select-arrow {
Expand Down
Loading

0 comments on commit 12c910e

Please sign in to comment.