Skip to content

Commit e218b12

Browse files
committed
feat(): md-input
1 parent 540099e commit e218b12

File tree

15 files changed

+914
-1
lines changed

15 files changed

+914
-1
lines changed

src/components/input/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# mdInput
2+
3+
Inputs are the basic input component of Material 2. The spec can be found [here](https://www.google.com/design/spec/components/text-fields.html).
4+
5+
6+
7+
## Type
8+
9+
At the time of writing this README, the `[type]` attribute is copied to the actual `<input>` element in the `<md-input>`.
10+
11+
The valid `type` attribute values are any supported by your browser, with the exception of `file`, `checkbox` and `radio`. File inputs aren't supported for now, while check boxes and radio buttons have their own components.
12+
13+
## Prefix and Suffix
14+
15+
You can include HTML before, and after the input tag.

src/components/input/input.html

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<div class="md-input-wrapper" (click)="input.focus()">
2+
<div class="md-input-table">
3+
<div class="md-input-prefix"><ng-content select="[md-prefix]"></ng-content></div>
4+
5+
<label class="md-input-placeholder"
6+
[attr.for]="id"
7+
[class.md-empty]="empty"
8+
[class.md-focused]="focused"
9+
[class.md-float]="floatingPlaceholder"
10+
[class.md-accent]="dividerColor == 'accent'"
11+
*ngIf="hasPlaceholder()">
12+
<ng-content select="md-placeholder"></ng-content>
13+
{{placeholder}}
14+
<span class="md-placeholder-required" *ngIf="required">*</span>
15+
</label>
16+
17+
<input #input
18+
aria-target
19+
class="md-input-element"
20+
[class.md-end]="align == 'end'"
21+
[attr.aria-label]="ariaLabel"
22+
[attr.aria-labelledby]="ariaLabelledBy"
23+
[attr.aria-disabled]="ariaDisabled"
24+
[attr.aria-required]="ariaRequired"
25+
[attr.aria-invalid]="ariaInvalid"
26+
[id]="id"
27+
[disabled]="disabled"
28+
[required]="required"
29+
[attr.maxlength]="maxLength"
30+
[type]="type"
31+
(focus)="onFocus()"
32+
(blur)="onBlur()"
33+
[(ngModel)]="value">
34+
35+
<div class="md-input-suffix"><ng-content select="[md-suffix]"></ng-content></div>
36+
</div>
37+
38+
<div class="md-input-underline"
39+
[class.md-disabled]="disabled">
40+
<span class="md-input-ripple"
41+
[class.md-focused]="focused"
42+
[class.md-accent]="dividerColor == 'accent'"></span>
43+
</div>
44+
45+
<div *ngIf="hintLabel != ''" class="md-hint">{{hintLabel}}</div>
46+
<ng-content select="md-hint"></ng-content>
47+
</div>

src/components/input/input.scss

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
@import 'default-theme';
2+
@import 'mixins';
3+
@import 'variables';
4+
5+
6+
// Placeholder colors. Required is used for the `*` star shown in the placeholder.
7+
$md-input-placeholder-color: md-color($md-foreground, hint-text);
8+
$md-input-floating-placeholder-color: md-color($md-primary);
9+
$md-input-required-placeholder-color: md-color($md-accent);
10+
11+
// Underline colors.
12+
$md-input-underline-color: md-color($md-foreground, hint-text);
13+
$md-input-underline-color-accent: md-color($md-accent);
14+
$md-input-underline-disabled-color: md-color($md-foreground, hint-text);
15+
$md-input-underline-focused-color: md-color($md-primary);
16+
17+
// Gradient for showing the dashed line when the input is disabled.
18+
$md-input-underline-disabled-background-image: linear-gradient(to right,
19+
rgba(0,0,0,0.26) 0%, rgba(0,0,0,0.26) 33%, transparent 0%);
20+
21+
:host {
22+
display: inline-block;
23+
position: relative;
24+
font-family: $md-font-family;
25+
26+
// Global wrapper. We need to apply margin to the element for spacing, but
27+
// cannot apply it to the host element directly.
28+
.md-input-wrapper {
29+
margin: 16px 0;
30+
}
31+
32+
// We use a table layout to baseline align the prefix and suffix classes.
33+
// The underline is outside of it so it can cover all of the elements under
34+
// this table.
35+
// Flex does not respect the baseline. What we really want is akin to a table
36+
// as want an inline-block where elements don't wrap.
37+
.md-input-table {
38+
display: inline-table;
39+
flex-flow: column;
40+
vertical-align: bottom;
41+
width: 100%;
42+
43+
& > * {
44+
display: table-cell;
45+
}
46+
}
47+
48+
// The Input element proper.
49+
.md-input-element {
50+
// Font needs to be inherited, because by default <input> has a system font.
51+
font: inherit;
52+
53+
// By default, <input> has a padding, border, outline and a default width.
54+
border: none;
55+
outline: none;
56+
padding: 0;
57+
width: 100%;
58+
59+
&.md-end {
60+
text-align: right;
61+
}
62+
}
63+
64+
// The placeholder label. This is invisible unless it is. The logic to show it is
65+
// basically `empty || (float && (!empty || focused))`. Float is dependent on the
66+
// `floatingPlaceholder` input.
67+
.md-input-placeholder {
68+
position: absolute;
69+
visibility: hidden;
70+
font-size: 100%;
71+
pointer-events: none; // We shouldn't catch mouse events (let them through).
72+
color: $md-input-placeholder-color;
73+
z-index: 1;
74+
75+
width: 100%;
76+
77+
transform: translateY(0);
78+
transform-origin: bottom left;
79+
transition: transform $swift-ease-out-duration $swift-ease-out-timing-function,
80+
scale $swift-ease-out-duration $swift-ease-out-timing-function,
81+
color $swift-ease-out-duration $swift-ease-out-timing-function;
82+
83+
&.md-empty {
84+
visibility: visible;
85+
cursor: text;
86+
}
87+
88+
// Show the placeholder above the input when it's not empty, or focused.
89+
&.md-float:not(.md-empty), &.md-float.md-focused {
90+
visibility: visible;
91+
padding-bottom: 5px;
92+
transform: translateY(-100%) scale(0.75);
93+
94+
.md-placeholder-required {
95+
color: $md-input-required-placeholder-color;
96+
}
97+
}
98+
99+
// :focus is applied to the input, but we apply md-focused to the other elements
100+
// that need to listen to it.
101+
&.md-focused {
102+
color: $md-input-floating-placeholder-color;
103+
104+
&.md-accent {
105+
color: $md-input-underline-color-accent;
106+
}
107+
}
108+
}
109+
110+
// The underline is what's shown under the input, its prefix and its suffix.
111+
// The ripple is the blue animation coming on top of it.
112+
.md-input-underline {
113+
position: absolute;
114+
height: 1px;
115+
width: 100%;
116+
margin-top: 4px;
117+
border-top: 1px solid $md-input-underline-color;
118+
119+
&.md-disabled {
120+
border-top: 0;
121+
background-image: $md-input-underline-disabled-background-image;
122+
background-position: 0;
123+
background-size: 4px 1px;
124+
background-repeat: repeat-x;
125+
}
126+
127+
.md-input-ripple {
128+
position: absolute;
129+
height: 2px;
130+
z-index: 1;
131+
background-color: $md-input-underline-focused-color;
132+
top: -1px;
133+
width: 100%;
134+
transform-origin: top;
135+
opacity: 0;
136+
transform: scaleY(0);
137+
transition: transform $swift-ease-out-duration $swift-ease-out-timing-function,
138+
opacity $swift-ease-out-duration $swift-ease-out-timing-function;
139+
140+
&.md-accent {
141+
background-color: $md-input-underline-color-accent;
142+
}
143+
144+
&.md-focused {
145+
opacity: 1;
146+
transform: scaleY(1);
147+
}
148+
}
149+
}
150+
151+
// The hint is shown below the underline. There can be more than one; one at the start
152+
// and one at the end.
153+
.md-hint {
154+
position: absolute;
155+
font-size: 75%;
156+
bottom: -0.5em;
157+
158+
&.md-right {
159+
right: 0;
160+
}
161+
}
162+
}
163+
164+
165+
// RTL support.
166+
:host-context([dir="rtl"]) {
167+
.md-input-placeholder {
168+
transform-origin: bottom right;
169+
}
170+
171+
.md-input-element.md-end {
172+
text-align: left;
173+
}
174+
175+
.md-hint {
176+
right: 0;
177+
left: auto;
178+
179+
&.md-right {
180+
right: auto;
181+
left: 0;
182+
}
183+
}
184+
}

0 commit comments

Comments
 (0)