Skip to content

component: MdInput #161

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 31, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions src/components/input/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# mdInput

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).

### Screenshots



## Type

At the time of writing this README, the `[type]` attribute is copied to the actual `<input>` element in the `<md-input>`.

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.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

except file?

## Prefix and Suffix

You can include HTML before, and after the input tag, as prefix or suffix. It will be underlined as per the Material specification, and clicking it will focus the input.

To add a prefix, use the `md-prefix` attribute on the element. Similarly, to add a suffix, use the `md-suffix` attribute. For example, in a template:

```html
<md-input type="number" placeholder="amount">
<span md-prefix>$</span>
<span md-suffix>.00</span>
</md-input>
```

Will result in this:

!!!! INSERT SCREENSHOT HERE.


## Hint Labels

Hint labels are the labels that shows the underline. You can have up to two hint labels; one on the `start` of the line (left in an LTR language, right in RTL), or one on the `end`.

You specify a hint-label in one of two ways; either using the `hintLabel` attribute, or using an `<md-hint>` directive in the `<md-input>`, which takes an `align` attribute containing the side. The attribute version is assumed to be at the `start`.

Specifying a side twice will result in an exception during initialization.

## Divider Color

47 changes: 47 additions & 0 deletions src/components/input/input.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<div class="md-input-wrapper" (click)="input.focus()">
<div class="md-input-table">
<div class="md-input-prefix"><ng-content select="[md-prefix]"></ng-content></div>

<label class="md-input-placeholder"
[attr.for]="id"
[class.md-empty]="empty"
[class.md-focused]="focused"
[class.md-float]="floatingPlaceholder"
[class.md-accent]="dividerColor == 'accent'"
*ngIf="hasPlaceholder()">
<ng-content select="md-placeholder"></ng-content>
{{placeholder}}
<span class="md-placeholder-required" *ngIf="required">*</span>
</label>

<input #input
aria-target
class="md-input-element"
[class.md-end]="align == 'end'"
[attr.aria-label]="ariaLabel"
[attr.aria-labelledby]="ariaLabelledBy"
[attr.aria-disabled]="ariaDisabled"
[attr.aria-required]="ariaRequired"
[attr.aria-invalid]="ariaInvalid"
[id]="id"
[disabled]="disabled"
[required]="required"
[attr.maxlength]="maxLength"
[type]="type"
(focus)="onFocus()"
(blur)="onBlur()"
[(ngModel)]="value">

<div class="md-input-suffix"><ng-content select="[md-suffix]"></ng-content></div>
</div>

<div class="md-input-underline"
[class.md-disabled]="disabled">
<span class="md-input-ripple"
[class.md-focused]="focused"
[class.md-accent]="dividerColor == 'accent'"></span>
</div>

<div *ngIf="hintLabel != ''" class="md-hint">{{hintLabel}}</div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No actions now, but my gut is worried about each input having ~25 bindings. Something to explore later.

(I could just be clinging to Angular 1 performance concerns, though)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted. There should be a greater task of performance checks AND visual checking before full release. In beta maybe.

Also, https://www.youtube.com/watch?v=fpaQpyU_QiM

<ng-content select="md-hint"></ng-content>
</div>
184 changes: 184 additions & 0 deletions src/components/input/input.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
@import 'default-theme';
@import 'mixins';
@import 'variables';


// Placeholder colors. Required is used for the `*` star shown in the placeholder.
$md-input-placeholder-color: md-color($md-foreground, hint-text);
$md-input-floating-placeholder-color: md-color($md-primary);
$md-input-required-placeholder-color: md-color($md-accent);

// Underline colors.
$md-input-underline-color: md-color($md-foreground, hint-text);
$md-input-underline-color-accent: md-color($md-accent);
$md-input-underline-disabled-color: md-color($md-foreground, hint-text);
$md-input-underline-focused-color: md-color($md-primary);

// Gradient for showing the dashed line when the input is disabled.
$md-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%);

:host {
display: inline-block;
position: relative;
font-family: $md-font-family;

// Global wrapper. We need to apply margin to the element for spacing, but
// cannot apply it to the host element directly.
.md-input-wrapper {
margin: 16px 0;
}

// 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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you talk about why display: inline-table is more suitable for this than other approaches (especially flex)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took a shot, but my brain is a jello today.

// Flex does not respect the baseline. What we really want is akin to a table
// as want an inline-block where elements don't wrap.
.md-input-table {
display: inline-table;
flex-flow: column;
vertical-align: bottom;
width: 100%;

& > * {
display: table-cell;
}
}

// The Input element proper.
.md-input-element {
// Font needs to be inherited, because by default <input> has a system font.
font: inherit;

// By default, <input> has a padding, border, outline and a default width.
border: none;
outline: none;
padding: 0;
width: 100%;

&.md-end {
text-align: right;
}
}

// The placeholder label. This is invisible unless it is. The logic to show it is
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"This is invisible unless it is."

Deep.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Knew you'd like :)

// basically `empty || (float && (!empty || focused))`. Float is dependent on the
// `floatingPlaceholder` input.
.md-input-placeholder {
position: absolute;
visibility: hidden;
font-size: 100%;
pointer-events: none; // We shouldn't catch mouse events (let them through).
color: $md-input-placeholder-color;
z-index: 1;

width: 100%;

transform: translateY(0);
transform-origin: bottom left;
transition: transform $swift-ease-out-duration $swift-ease-out-timing-function,
scale $swift-ease-out-duration $swift-ease-out-timing-function,
color $swift-ease-out-duration $swift-ease-out-timing-function;

&.md-empty {
visibility: visible;
cursor: text;
}

// Show the placeholder above the input when it's not empty, or focused.
&.md-float:not(.md-empty), &.md-float.md-focused {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add comment to explain what this state means

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

visibility: visible;
padding-bottom: 5px;
transform: translateY(-100%) scale(0.75);

.md-placeholder-required {
color: $md-input-required-placeholder-color;
}
}

// :focus is applied to the input, but we apply md-focused to the other elements
// that need to listen to it.
&.md-focused {
color: $md-input-floating-placeholder-color;

&.md-accent {
color: $md-input-underline-color-accent;
}
}
}

// The underline is what's shown under the input, its prefix and its suffix.
// The ripple is the blue animation coming on top of it.
.md-input-underline {
position: absolute;
height: 1px;
width: 100%;
margin-top: 4px;
border-top: 1px solid $md-input-underline-color;

&.md-disabled {
border-top: 0;
background-image: $md-input-underline-disabled-background-image;
background-position: 0;
background-size: 4px 1px;
background-repeat: repeat-x;
}

.md-input-ripple {
position: absolute;
height: 2px;
z-index: 1;
background-color: $md-input-underline-focused-color;
top: -1px;
width: 100%;
transform-origin: top;
opacity: 0;
transform: scaleY(0);
transition: transform $swift-ease-out-duration $swift-ease-out-timing-function,
opacity $swift-ease-out-duration $swift-ease-out-timing-function;

&.md-accent {
background-color: $md-input-underline-color-accent;
}

&.md-focused {
opacity: 1;
transform: scaleY(1);
}
}
}

// The hint is shown below the underline. There can be more than one; one at the start
// and one at the end.
.md-hint {
position: absolute;
font-size: 75%;
bottom: -0.5em;

&.md-right {
right: 0;
}
}
}


// RTL support.
:host-context([dir="rtl"]) {
.md-input-placeholder {
transform-origin: bottom right;
}

.md-input-element.md-end {
text-align: left;
}

.md-hint {
right: 0;
left: auto;

&.md-right {
right: auto;
left: 0;
}
}
}
Loading