-
Notifications
You must be signed in to change notification settings - Fork 6.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(select): basic selection and animations (#1647)
- Loading branch information
Showing
15 changed files
with
871 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,5 @@ | ||
<md-select></md-select> | ||
<div class="demo-select"> | ||
<md-select placeholder="Food"> | ||
<md-option *ngFor="let food of foods"> {{ food.viewValue }} </md-option> | ||
</md-select> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.demo-select { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## Work in progress! | ||
|
||
The select is still a work in progress, so most features have not been implemented. Not ready for use! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,22 @@ | ||
import {NgModule, ModuleWithProviders} from '@angular/core'; | ||
import {CommonModule} from '@angular/common'; | ||
import {MdSelect} from './select'; | ||
import {MdOption} from './option'; | ||
import {OverlayModule} from '../core/overlay/overlay-directives'; | ||
import {MdRippleModule} from '../core/ripple/ripple'; | ||
import {OVERLAY_PROVIDERS} from '../core/overlay/overlay'; | ||
export * from './select'; | ||
|
||
@NgModule({ | ||
imports: [], | ||
imports: [CommonModule, OverlayModule, MdRippleModule], | ||
exports: [MdSelect, MdOption], | ||
declarations: [MdSelect, MdOption], | ||
}) | ||
export class MdSelectModule { | ||
static forRoot(): ModuleWithProviders { | ||
return { | ||
ngModule: MdSelectModule, | ||
providers: [] | ||
providers: [OVERLAY_PROVIDERS] | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<ng-content></ng-content> | ||
<div class="md-option-ripple" md-ripple md-ripple-background-color="rgba(0,0,0,0)" | ||
[md-ripple-trigger]="_getHostElement()"></div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,75 @@ | ||
import {Component, ViewEncapsulation} from '@angular/core'; | ||
import { | ||
Component, | ||
ElementRef, | ||
EventEmitter, | ||
Output, | ||
Renderer, | ||
ViewEncapsulation | ||
} from '@angular/core'; | ||
import {ENTER, SPACE} from '../core/keyboard/keycodes'; | ||
|
||
@Component({ | ||
moduleId: module.id, | ||
selector: 'md-option', | ||
template: ``, | ||
host: { | ||
'role': 'option', | ||
'tabindex': '0', | ||
'[class.md-selected]': 'selected', | ||
'[attr.aria-selected]': 'selected.toString()', | ||
'(click)': 'select()', | ||
'(keydown)': '_handleKeydown($event)' | ||
}, | ||
templateUrl: 'option.html', | ||
styleUrls: ['select.css'], | ||
encapsulation: ViewEncapsulation.None | ||
}) | ||
export class MdOption {} | ||
export class MdOption { | ||
private _selected = false; | ||
|
||
/** Event emitted when the option is selected. */ | ||
@Output() onSelect = new EventEmitter(); | ||
|
||
constructor(private _element: ElementRef, private _renderer: Renderer) {} | ||
|
||
/** Whether or not the option is currently selected. */ | ||
get selected(): boolean { | ||
return this._selected; | ||
} | ||
|
||
/** | ||
* The displayed value of the option. It is necessary to show the selected option in the | ||
* select's trigger. | ||
* TODO(kara): Add input property alternative for node envs. | ||
*/ | ||
get viewValue(): string { | ||
return this._getHostElement().textContent.trim(); | ||
} | ||
|
||
/** Selects the option. */ | ||
select(): void { | ||
this._selected = true; | ||
this.onSelect.emit(); | ||
} | ||
|
||
/** Deselects the option. */ | ||
deselect(): void { | ||
this._selected = false; | ||
} | ||
|
||
/** Sets focus onto this option. */ | ||
focus(): void { | ||
this._renderer.invokeElementMethod(this._getHostElement(), 'focus'); | ||
} | ||
|
||
/** Ensures the option is selected when activated from the keyboard. */ | ||
_handleKeydown(event: KeyboardEvent): void { | ||
if (event.keyCode === ENTER || event.keyCode === SPACE) { | ||
this.select(); | ||
} | ||
} | ||
|
||
_getHostElement(): HTMLElement { | ||
return this._element.nativeElement; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { | ||
animate, | ||
AnimationEntryMetadata, | ||
state, | ||
style, | ||
transition, | ||
trigger, | ||
} from '@angular/core'; | ||
|
||
/** | ||
* The following are all the animations for the md-select component, with each | ||
* const containing the metadata for one animation. | ||
* | ||
* The values below match the implementation of the Material 1 md-select animation. | ||
*/ | ||
|
||
/** | ||
* This animation shrinks the placeholder text to 75% of its normal size and translates | ||
* it to either the top left corner (ltr) or top right corner (rtl) of the trigger, | ||
* depending on the text direction of the application. | ||
*/ | ||
export const transformPlaceholder: AnimationEntryMetadata = trigger('transformPlaceholder', [ | ||
state('normal', style({ | ||
transform: `translate3d(0, 0, 0) scale(1)` | ||
})), | ||
state('floating-ltr', style({ | ||
transform: `translate3d(-2px, -22px, 0) scale(0.75)` | ||
})), | ||
state('floating-rtl', style({ | ||
transform: `translate3d(2px, -22px, 0) scale(0.75)` | ||
})), | ||
transition('* => *', animate(`400ms cubic-bezier(0.25, 0.8, 0.25, 1)`)) | ||
]); | ||
|
||
/** | ||
* This animation transforms the select's overlay panel on and off the page. | ||
* | ||
* When the panel is attached to the DOM, it expands its width 32px, scales it up to | ||
* 100% on the Y axis, fades in its border, and translates slightly up and to the | ||
* side to ensure the option text correctly overlaps the trigger text. | ||
* | ||
* When the panel is removed from the DOM, it simply fades out linearly. | ||
*/ | ||
export const transformPanel: AnimationEntryMetadata = trigger('transformPanel', [ | ||
state('showing-ltr', style({ | ||
opacity: 1, | ||
width: 'calc(100% + 32px)', | ||
transform: `translate3d(-16px, -9px, 0) scaleY(1)` | ||
})), | ||
state('showing-rtl', style({ | ||
opacity: 1, | ||
width: 'calc(100% + 32px)', | ||
transform: `translate3d(16px, -9px, 0) scaleY(1)` | ||
})), | ||
transition('void => *', [ | ||
style({ | ||
opacity: 0, | ||
width: '100%', | ||
transform: `translate3d(0, 0, 0) scaleY(0)` | ||
}), | ||
animate(`150ms cubic-bezier(0.55, 0, 0.55, 0.2)`) | ||
]), | ||
transition('* => void', [ | ||
animate('250ms linear', style({opacity: 0})) | ||
]) | ||
]); | ||
|
||
/** | ||
* This animation fades in the background color and text content of the | ||
* select's options. It is time delayed to occur 100ms after the overlay | ||
* panel has transformed in. | ||
*/ | ||
export const fadeInContent: AnimationEntryMetadata = trigger('fadeInContent', [ | ||
state('showing', style({opacity: 1})), | ||
transition('void => showing', [ | ||
style({opacity: 0}), | ||
animate(`150ms 100ms cubic-bezier(0.55, 0, 0.55, 0.2)`) | ||
]) | ||
]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,15 @@ | ||
I'm a select! | ||
<div class="md-select-trigger" overlay-origin (click)="toggle()" #origin="overlayOrigin" #trigger> | ||
<span class="md-select-placeholder" [@transformPlaceholder]="_getPlaceholderState()"> {{ placeholder }} </span> | ||
<span class="md-select-value" *ngIf="selected"> {{ selected?.viewValue }} </span> | ||
<span class="md-select-arrow"></span> | ||
</div> | ||
|
||
<template connected-overlay [origin]="origin" [open]="panelOpen" hasBackdrop (backdropClick)="close()" | ||
backdropClass="md-overlay-transparent-backdrop" [positions]="_positions" [width]="_getWidth()"> | ||
<div class="md-select-panel" [@transformPanel]="_getPanelState()" (@transformPanel.done)="_onPanelDone()" | ||
(keydown)="_keyManager.onKeydown($event)"> | ||
<div class="md-select-content" [@fadeInContent]="'showing'"> | ||
<ng-content></ng-content> | ||
</div> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
@import '../core/style/menu-common'; | ||
|
||
$md-select-trigger-height: 30px !default; | ||
$md-select-trigger-min-width: 112px !default; | ||
$md-select-arrow-size: 5px !default; | ||
|
||
md-select { | ||
display: inline-block; | ||
outline: none; | ||
} | ||
|
||
.md-select-trigger { | ||
display: flex; | ||
justify-content: space-between; | ||
align-items: center; | ||
height: $md-select-trigger-height; | ||
min-width: $md-select-trigger-min-width; | ||
cursor: pointer; | ||
} | ||
|
||
.md-select-placeholder { | ||
padding: 0 2px; | ||
transform-origin: left top; | ||
|
||
[dir='rtl'] & { | ||
transform-origin: right top; | ||
} | ||
} | ||
|
||
.md-select-value { | ||
position: absolute; | ||
} | ||
|
||
.md-select-arrow { | ||
width: 0; | ||
height: 0; | ||
border-left: $md-select-arrow-size solid transparent; | ||
border-right: $md-select-arrow-size solid transparent; | ||
border-top: $md-select-arrow-size solid; | ||
} | ||
|
||
.md-select-panel { | ||
@include md-menu-base(); | ||
padding-top: 0; | ||
padding-bottom: 0; | ||
transform-origin: top; | ||
} | ||
|
||
md-option { | ||
@include md-menu-item-base(); | ||
position: relative; | ||
cursor: pointer; | ||
outline: none; | ||
} | ||
|
||
.md-option-ripple { | ||
position: absolute; | ||
top: 0; | ||
left: 0; | ||
bottom: 0; | ||
right: 0; | ||
} |
Oops, something went wrong.