chore(): remove all angular2_material code.

This commit is contained in:
Jeremy Elbourn 2016-03-16 11:11:20 -07:00
parent 310620fd12
commit d61aaac400
95 changed files with 20 additions and 4879 deletions

View File

@ -40,9 +40,9 @@ if (cliArgs.projects) {
cliArgs.projects.split(',').sort().join(',');
}
// --projects=angular2,angular2_material => {angular2: true, angular2_material: true}
// --projects=angular2 => {angular2: true}
var allProjects =
'angular1_router,angular2,angular2_material,benchmarks,benchmarks_external,benchpress,playground,payload_tests,bundle_deps';
'angular1_router,angular2,benchmarks,benchmarks_external,benchpress,playground,payload_tests,bundle_deps';
var cliArgsProjects = (cliArgs.projects || allProjects)
.split(',')
.reduce((map, projectName) => {
@ -57,7 +57,7 @@ function printModulesWarning() {
console.warn(
"Pro Tip: Did you know that you can speed up your build by specifying project name(s)?");
console.warn(" It's like pressing the turbo button in the old days, but better!");
console.warn(" Examples: --project=angular2 or --project=angular2,angular2_material");
console.warn(" Examples: --project=angular2 or --project=angular2");
}
}
@ -391,21 +391,19 @@ gulp.task('serve.js.dev', ['build.js.dev', 'build.js.cjs'], function(neverDone)
gulp.task('serve.js.prod', jsServeProd);
gulp.task('serve.e2e.dev', ['build.js.dev', 'build.js.cjs', 'build.css.material'],
function(neverDone) {
var watch = require('./tools/build/watch');
gulp.task('serve.e2e.dev', ['build.js.dev', 'build.js.cjs'], function(neverDone) {
var watch = require('./tools/build/watch');
watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.dev', '!build.js.cjs']);
jsServeDev();
});
watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.dev', '!build.js.cjs']);
jsServeDev();
});
gulp.task('serve.e2e.prod', ['build.js.prod', 'build.js.cjs', 'build.css.material'],
function(neverDone) {
var watch = require('./tools/build/watch');
gulp.task('serve.e2e.prod', ['build.js.prod', 'build.js.cjs'], function(neverDone) {
var watch = require('./tools/build/watch');
watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.prod', '!build.js.cjs']);
jsServeProd();
});
watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.prod', '!build.js.cjs']);
jsServeProd();
});
gulp.task('serve.js.dart2js', jsServeDartJs);
@ -440,7 +438,7 @@ gulp.task('serve.e2e.dart', ['build.js.cjs'], function(neverDone) {
// Note: we are not using build.dart as the dart analyzer takes too long...
watch('modules/**', {ignoreInitial: true}, ['!build/tree.dart', '!build.js.cjs']);
runSequence('build/packages.dart', 'build/pubspec.dart', 'build.dart.material.css', 'serve.dart');
runSequence('build/packages.dart', 'build/pubspec.dart', 'serve.dart');
});
@ -774,8 +772,7 @@ gulp.task('!checkAndReport.payload.js', function() {
gulp.task('watch.dart.dev', function(done) {
runSequence('build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart',
'!build/change_detect.dart', '!build/remove-pub-symlinks', 'build.dart.material.css',
function(error) {
'!build/change_detect.dart', '!build/remove-pub-symlinks', function(error) {
var watch = require('./tools/build/watch');
// if initial build failed (likely due to build or formatting step) then exit
@ -1053,7 +1050,7 @@ gulp.task('build/packages.dart', function(done) {
// Builds and compiles all Dart packages
gulp.task('build.dart', function(done) {
runSequence('build/packages.dart', 'build/pubspec.dart', 'build/analyze.dart',
'build/check.apidocs.dart', 'build.dart.material.css', sequenceComplete(done));
'build/check.apidocs.dart', sequenceComplete(done));
});
@ -1112,9 +1109,8 @@ gulp.task('!broccoli.js.prod', () => angularBuilder.rebuildBrowserProdTree({
useBundles: cliArgs.useBundles
}));
gulp.task('build.js.dev', ['build/clean.js'], function(done) {
runSequence('broccoli.js.dev', 'build.css.material', sequenceComplete(done));
});
gulp.task('build.js.dev', ['build/clean.js'],
function(done) { runSequence('broccoli.js.dev', sequenceComplete(done)); });
gulp.task('build.js.prod', ['build.tools'],
function(done) { runSequence('!broccoli.js.prod', sequenceComplete(done)); });
@ -1471,41 +1467,6 @@ gulp.task('!build/change_detect.dart', function(done) {
});
// ------------
// angular material testing rules
gulp.task('build.css.material', function() {
var autoprefixer = require('gulp-autoprefixer');
var sass = require('gulp-sass');
return gulp.src('modules/*/src/**/*.scss')
.pipe(sass())
.pipe(autoprefixer())
.pipe(gulp.dest(CONFIG.dest.js.prod.es5))
.pipe(gulp.dest(CONFIG.dest.js.dev.es5))
.pipe(gulp.dest(CONFIG.dest.js.dart2js + '/examples/packages'));
});
gulp.task('build.js.material', function(done) {
runSequence('build.js.dev', 'build.css.material', sequenceComplete(done));
});
gulp.task('build.dart2js.material', function(done) {
runSequence('build.dart', 'build.css.material', sequenceComplete(done));
});
gulp.task('build.dart.material.css', function() {
var autoprefixer = require('gulp-autoprefixer');
var sass = require('gulp-sass');
return gulp.src('dist/dart/angular2_material/src/**/*.scss')
.pipe(sass())
.pipe(autoprefixer())
.pipe(gulp.dest('dist/dart/angular2_material/lib/src'));
});
gulp.task('build.dart.material', ['build/packages.dart'], function(done) {
runSequence('build/packages.dart', 'build.dart.material.css', sequenceComplete(done));
});
gulp.task('cleanup.builder', function() { return angularBuilder.cleanup(); });

View File

@ -1,12 +0,0 @@
Language: JavaScript
BasedOnStyle: Google
ColumnLimit: 100
TabWidth: 2
ContinuationIndentWidth: 4
MaxEmptyLinesToKeep : 2
AllowShortBlocksOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty

View File

@ -1 +0,0 @@
Temporary home of Material Design components for Angular 2.

View File

@ -1,21 +0,0 @@
{
"name": "angular2_material",
"version": "<%= packageJson.version %>",
"description": "Google material design components for Angular 2",
"homepage": "<%= packageJson.homepage %>",
"bugs": "<%= packageJson.bugs %>",
"contributors": <%= JSON.stringify(packageJson.contributors) %>,
"license": "<%= packageJson.license %>",
"repository": <%= JSON.stringify(packageJson.repository) %>,
"dependencies": {
"es6-promise": "<%= packageJson.dependencies['es6-promise'] %>",
"es6-shim": "<%= packageJson.dependencies['es6-shim'] %>",
"reflect-metadata": "<%= packageJson.dependencies['reflect-metadata'] %>",
"rxjs": "<%= packageJson.dependencies['rxjs'] %>",
"zone.js": "<%= packageJson.dependencies['zone.js'] %>"
},
"devDependencies": <%= JSON.stringify(packageJson.defaultDevDependencies) %>
"peerDependencies": {
"angular2": "<%= packageJson.version %>"
}
}

View File

@ -1,20 +0,0 @@
name: angular2_material
version: <%= packageJson.version %>
authors:
<%= Object.keys(packageJson.contributors).map(function(name) {
return '- '+name+' <'+packageJson.contributors[name]+'>';
}).join('\n') %>
description: Google material design components for Angular 2
homepage: <%= packageJson.homepage %>
environment:
sdk: '>=1.10.0 <2.0.0'
dependencies:
angular2: '^<%= packageJson.version %>'
browser: '^0.10.0'
dependency_overrides:
angular2:
path: ../angular2
dev_dependencies:
guinness2: '0.0.4'
transformers:
- angular2/transform/codegen

View File

@ -1 +0,0 @@
<span class="md-button-wrapper"><ng-content></ng-content></span>

View File

@ -1,195 +0,0 @@
@import "../../core/style/variables";
@import "../../core/style/shadows";
// TODO(jelbourn): This goes away.
@import "../../core/style/default-theme";
// TODO(jelbourn): Move variables and mixins into a partial file.
// TODO(jelbourn): Measure perf benefits for translate3d and will-change.
// TODO(jelbourn): Figure out if anchor hover underline actually happens in any browser.
// Standard button sizing.
$md-button-padding: 0 rem(0.600) !default;
$md-button-min-width: rem(8.800) !default;
$md-button-margin: rem(0.600) rem(0.800) !default;
$md-button-line-height: rem(3.60) !default;
$md-button-border-radius: 3px !default;
// FAB sizing.
$md-fab-size: rem(5.600) !default;
$md-fab-line-height: rem(5.600) !default;
$md-fab-padding: rem(1.60) !default;
$md-fab-mini-size: rem(4.00) !default;
$md-fab-mini-line-height: rem(4.00) !default;
/** Mixin to create distinct classes for fab positions, e.g. ".md-fab-position-bottom-right". */
@mixin md-fab-position($spot, $top: auto, $right: auto, $bottom: auto, $left: auto) {
.md-fab-position-#{$spot} {
top: $top;
right: $right;
bottom: $bottom;
left: $left;
position: absolute;
}
}
/** Styles for all disabled buttons. */
@mixin md-button-disabled() {
color: md-color($md-foreground, disabled);
background-color: transparent;
cursor: default;
}
/** Base styles for all buttons. */
@mixin md-button-base() {
box-sizing: border-box;
position: relative;
// Reset browser <button> styles.
background: transparent;
text-align: center;
overflow: hidden;
cursor: pointer;
user-select: none;
outline: none;
border: none;
// Make anchors render like buttons.
display: inline-block;
white-space: nowrap;
text-decoration: none;
vertical-align: middle;
// Typography.
font-size: $md-body-font-size-base;
font-weight: 500;
// Sizing.
padding: $md-button-padding;
margin: $md-button-margin;
min-width: $md-button-min-width;
line-height: $md-button-line-height;
border-radius: $md-button-border-radius;
// Animation.
transition: background $swift-ease-out-duration $swift-ease-out-timing-function,
box-shadow $swift-ease-out-duration $swift-ease-out-timing-function;
// Hide the browser focus indicator, instead applying our own focus style on background-color.
&:focus {
outline: none;
}
&:hover, &:focus {
// Remove anchor underline again for more specific modifiers.
text-decoration: none;
}
// Use a CSS class for focus style because we only want to render the focus style when
// the focus originated from a keyboard event (see JS source for more details).
&:hover, &.md-button-focus {
background: md-color($md-background, 500, 0.2);
}
&.md-primary {
color: md-color($md-primary);
}
&.md-accent {
color: md-color($md-accent);
}
// Use the [disabled] attribute instead of the :disabled pseudo-class because anchors
// cannot technically be :disabled.
&[disabled] {
@include md-button-disabled();
}
}
/** Base styles for raised buttons, including FABs. */
@mixin md-raised-button() {
@include md-button-base();
// Force hardware acceleration.
transform: translate3d(0, 0, 0);
box-shadow: $md-shadow-bottom-z-1;
&:active {
box-shadow: $md-shadow-bottom-z-2;
}
&[disabled] {
box-shadow: none;
}
&.md-primary {
color: md-color($md-primary, default-contrast);
background-color: md-color($md-primary);
&:hover, &.md-button-focus {
background-color: md-color($md-primary, 600);
}
}
&.md-accent {
color: md-color($md-accent, default-contrast);
background-color: md-color($md-accent);
&:hover, &.md-button-focus {
background-color: md-color($md-accent, A700);
}
}
&.md-primary, &.md-accent {
&[disabled] {
@include md-button-disabled();
}
}
}
[mdButton] {
@include md-button-base();
}
[mdRaisedButton] {
@include md-raised-button();
color: md-color($md-background, default-contrast);
background-color: md-color($md-background, 50);
}
[mdFab] {
@include md-raised-button();
z-index: $z-index-fab;
border-radius: 50%;
min-width: 0;
width: $md-fab-size;
height: $md-fab-size;
line-height: $md-fab-line-height;
vertical-align: middle;
&.md-mini {
line-height: $md-fab-mini-line-height;
width: $md-fab-mini-size;
height: $md-fab-mini-size;
}
}
// Styles for high contrast mode.
@media screen and (-ms-high-contrast: active) {
[md-raised],
[mdFab] {
border: 1px solid #fff;
}
}
$md-fab-pos-offset: ($md-fab-size - $md-fab-padding) / 2;
@include md-fab-position(bottom-right, auto, $md-fab-pos-offset, $md-fab-pos-offset, auto);
@include md-fab-position(bottom-left, auto, auto, $md-fab-pos-offset, $md-fab-pos-offset);
@include md-fab-position(top-right, $md-fab-pos-offset, $md-fab-pos-offset, auto, auto);
@include md-fab-position(top-left, $md-fab-pos-offset, auto, auto, $md-fab-pos-offset);

View File

@ -1,93 +0,0 @@
import {Component, ViewEncapsulation, OnChanges} from 'angular2/core';
import {TimerWrapper} from 'angular2/src/facade/async';
import {isPresent} from 'angular2/src/facade/lang';
// TODO(jelbourn): Ink ripples.
// TODO(jelbourn): Make the `isMouseDown` stuff done with one global listener.
@Component({
selector: '[mdButton]:not(a), [mdFab]:not(a), [mdRaisedButton]:not(a)',
host: {
'(mousedown)': 'onMousedown()',
'(focus)': 'onFocus()',
'(blur)': 'onBlur()',
'[class.md-button-focus]': 'isKeyboardFocused',
},
templateUrl: 'package:angular2_material/src/components/button/button.html',
styleUrls: ['package:angular2_material/src/components/button/button.css'],
encapsulation: ViewEncapsulation.None,
})
export class MdButton {
/** Whether a mousedown has occurred on this element in the last 100ms. */
isMouseDown: boolean = false;
/** Whether the button has focus from the keyboard (not the mouse). Used for class binding. */
isKeyboardFocused: boolean = false;
onMousedown() {
// We only *show* the focus style when focus has come to the button via the keyboard.
// The Material Design spec is silent on this topic, and without doing this, the
// button continues to look :active after clicking.
// @see http://marcysutton.com/button-focus-hell/
this.isMouseDown = true;
TimerWrapper.setTimeout(() => {this.isMouseDown = false}, 100);
}
onFocus() {
this.isKeyboardFocused = !this.isMouseDown;
}
onBlur() {
this.isKeyboardFocused = false;
}
}
@Component({
selector: 'a[mdButton], a[mdRaisedButton], a[mdFab]',
inputs: ['disabled'],
host: {
'(click)': 'onClick($event)',
'(mousedown)': 'onMousedown()',
'(focus)': 'onFocus()',
'(blur)': 'onBlur()',
'[tabIndex]': 'tabIndex',
'[class.md-button-focus]': 'isKeyboardFocused',
'[attr.aria-disabled]': 'isAriaDisabled',
},
templateUrl: 'package:angular2_material/src/components/button/button.html',
encapsulation: ViewEncapsulation.None
})
export class MdAnchor extends MdButton implements OnChanges {
tabIndex: number;
disabled_: boolean;
get disabled(): boolean {
return this.disabled_;
}
set disabled(value) {
// The presence of *any* disabled value makes the component disabled, *except* for false.
this.disabled_ = isPresent(value) && this.disabled !== false;
}
onClick(event) {
// A disabled anchor shouldn't navigate anywhere.
if (this.disabled) {
event.preventDefault();
}
}
/** Invoked when a change is detected. */
ngOnChanges(_) {
// A disabled anchor should not be in the tab flow.
this.tabIndex = this.disabled ? -1 : 0;
}
/** Gets the aria-disabled value for the component, which must be a string for Dart. */
get isAriaDisabled(): string {
return this.disabled ? 'true' : 'false';
}
}

View File

@ -1,8 +0,0 @@
<style>@import "package:angular2_material/src/components/checkbox/checkbox.css";</style>
<div (click)="toggle($event)">
<div class="md-checkbox-container">
<div class="md-checkbox-icon"></div>
</div>
<div class="md-checkbox-label"><ng-content></ng-content></div>
</div>

View File

@ -1,176 +0,0 @@
@import "../../core/style/variables";
@import "../../core/style/shadows";
// TODO(jelbourn): This goes away.
@import "../../core/style/default-theme";
$checkbox-width: 18px !default;
$checkbox-height: $checkbox-width !default;
md-checkbox {
box-sizing: border-box;
display: block;
margin: 15px;
white-space: nowrap;
cursor: pointer;
outline: none;
user-select: none;
*, *:after {
box-sizing: border-box;
}
&[aria-checked="true"] .md-checkbox-icon {
border: none;
}
// Checkbox is disabled.
&[disabled] {
cursor: no-drop;
}
// Checkbox is focused.
&:focus .md-checkbox-label:not(:empty) {
border-color: black;
}
// Checkbox is checked.
&[aria-checked="true"] .md-checkbox-icon:after {
transform: rotate(45deg);
position: absolute;
left: 6px;
top: 2px;
display: table;
width: 6px;
height: 12px;
border: 2px solid;
border-top: 0;
border-left: 0;
content: ' ';
}
}
.md-checkbox-container {
position: relative;
top: 4px;
display: inline-block;
width: $checkbox-width;
height: $checkbox-height;
&:after {
content: '';
position: absolute;
top: -10px;
right: -10px;
bottom: -10px;
left: -10px;
}
.md-ripple-container {
position: absolute;
display: block;
width: auto;
height: auto;
left: -15px;
top: -15px;
right: -15px;
bottom: -15px;
}
}
// Checkbox is not checked.
.md-checkbox-icon {
transition: 240ms;
position: absolute;
top: 0;
left: 0;
width: $checkbox-width;
height: $checkbox-height;
border: 2px solid;
border-radius: 2px;
}
.md-checkbox-label {
border: 1px dotted transparent;
position: relative;
display: inline-block;
margin-left: 10px;
vertical-align: middle;
white-space: normal;
pointer-events: none;
user-select: text;
}
// THEME
// TODO(jelbourn): ripple
md-checkbox {
.md-ripple {
color: md-color($md-accent, 600);
}
&[aria-checked="true"] .md-ripple {
color: md-color($md-background, 600);
}
.md-checkbox-icon {
border-color: md-color($md-foreground, icon);
}
&[aria-checked="true"] .md-checkbox-icon {
background-color: md-color($md-accent, 0.87);
}
&[aria-checked="true"] .md-checkbox-icon:after {
border-color: md-color($md-background, 200);
}
&:not([disabled]) {
&.md-primary {
.md-ripple {
color: md-color($md-primary, 600);
}
&[aria-checked="true"] .md-ripple {
color: md-color($md-background, 600);
}
.md-checkbox-icon {
border-color: md-color($md-foreground, icon);
}
&[aria-checked="true"] .md-checkbox-icon {
background-color: md-color($md-primary, 0.87);
}
&[aria-checked="true"] .md-checkbox-icon:after {
border-color: md-color($md-background, 200);
}
}
&.md-warn {
.md-ripple {
color: md-color($md-warn, 600);
}
.md-checkbox-icon {
border-color: md-color($md-foreground, icon);
}
&[aria-checked="true"] .md-checkbox-icon {
background-color: md-color($md-warn, 0.87);
}
&[aria-checked="true"] .md-checkbox-icon:after {
border-color: md-color($md-background, 200);
}
}
}
&[disabled] {
.md-checkbox-icon {
border-color: md-color($md-foreground, disabled);
}
&[aria-checked="true"] .md-checkbox-icon {
background-color: md-color($md-foreground, disabled);
}
}
}

View File

@ -1,60 +0,0 @@
import {Component, Attribute, ViewEncapsulation} from 'angular2/core';
import {isPresent} from 'angular2/src/facade/lang';
import {KeyCodes} from 'angular2_material/src/core/key_codes';
import {KeyboardEvent} from 'angular2/src/facade/browser';
import {NumberWrapper} from 'angular2/src/facade/lang';
@Component({
selector: 'md-checkbox',
inputs: ['checked', 'disabled'],
host: {
'role': 'checkbox',
'[attr.aria-checked]': 'checked',
'[attr.aria-disabled]': 'disabled',
'[tabindex]': 'tabindex',
'(keydown)': 'onKeydown($event)',
},
templateUrl: 'package:angular2_material/src/components/checkbox/checkbox.html',
directives: [],
encapsulation: ViewEncapsulation.None
})
export class MdCheckbox {
/** Whether this checkbox is checked. */
checked: boolean;
/** Whether this checkbox is disabled. */
disabled_: boolean;
/** Setter for tabindex */
tabindex: number;
constructor(@Attribute('tabindex') tabindex: string) {
this.checked = false;
this.tabindex = isPresent(tabindex) ? NumberWrapper.parseInt(tabindex, 10) : 0;
this.disabled_ = false;
}
get disabled() {
return this.disabled_;
}
set disabled(value) {
this.disabled_ = isPresent(value) && value !== false;
}
onKeydown(event: KeyboardEvent) {
if (event.keyCode == KeyCodes.SPACE) {
event.preventDefault();
this.toggle(event);
}
}
toggle(event) {
if (this.disabled) {
event.stopPropagation();
return;
}
this.checked = !this.checked;
}
}

View File

@ -1,33 +0,0 @@
<style>
.md-dialog {
position: absolute;
z-index: 80;
/** Center the dialog. */
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
height: 300px;
background-color: white;
border: 1px solid black;
box-shadow: 0 4px 4px;;
padding: 20px;
}
.md-backdrop {
position: absolute;
top:0 ;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.12);
}
</style>
<md-dialog-content></md-dialog-content>
<div tabindex="0" (focus)="wrapFocus()"></div>

View File

@ -1,276 +0,0 @@
import {
bind,
provide,
forwardRef,
Component,
ComponentRef,
Directive,
DynamicComponentLoader,
ElementRef,
Host,
Injectable,
ResolvedProvider,
SkipSelf,
Injector,
ViewEncapsulation
} from 'angular2/core';
import {ObservableWrapper, PromiseWrapper} from 'angular2/src/facade/async';
import {isPresent, Type} from 'angular2/src/facade/lang';
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
import {MouseEvent, KeyboardEvent} from 'angular2/src/facade/browser';
import {KeyCodes} from 'angular2_material/src/core/key_codes';
import {PromiseCompleter} from 'angular2/src/facade/promise';
// TODO(jelbourn): Opener of dialog can control where it is rendered.
// TODO(jelbourn): body scrolling is disabled while dialog is open.
// TODO(jelbourn): Don't manually construct and configure a DOM element. See #1402
// TODO(jelbourn): Wrap focus from end of dialog back to the start. Blocked on #1251
// TODO(jelbourn): Focus the dialog element when it is opened.
// TODO(jelbourn): Real dialog styles.
// TODO(jelbourn): Pre-built `alert` and `confirm` dialogs.
// TODO(jelbourn): Animate dialog out of / into opening element.
/**
* Service for opening modal dialogs.
*/
@Injectable()
export class MdDialog {
componentLoader: DynamicComponentLoader;
constructor(loader: DynamicComponentLoader) {
this.componentLoader = loader;
}
/**
* Opens a modal dialog.
* @param type The component to open.
* @param elementRef The logical location into which the component will be opened.
* @param options
* @returns Promise for a reference to the dialog.
*/
open(type: Type, elementRef: ElementRef, options: MdDialogConfig = null): Promise<MdDialogRef> {
var config = isPresent(options) ? options : new MdDialogConfig();
// Create the dialogRef here so that it can be injected into the content component.
var dialogRef = new MdDialogRef();
var bindings = Injector.resolve([provide(MdDialogRef, {useValue: dialogRef})]);
var backdropRefPromise = this._openBackdrop(elementRef, bindings);
// First, load the MdDialogContainer, into which the given component will be loaded.
return this.componentLoader.loadNextToLocation(MdDialogContainer, elementRef)
.then /*<ComponentRef>*/ ((containerRef: ComponentRef) => {
// TODO(tbosch): clean this up when we have custom renderers
// (https://github.com/angular/angular/issues/1807)
// TODO(jelbourn): Don't use direct DOM access. Need abstraction to create an element
// directly on the document body (also needed for web workers stuff).
// Create a DOM node to serve as a physical host element for the dialog.
var dialogElement = containerRef.location.nativeElement;
DOM.appendChild(DOM.query('body'), dialogElement);
// TODO(jelbourn): Do this with hostProperties (or another rendering abstraction) once
// ready.
if (isPresent(config.width)) {
DOM.setStyle(dialogElement, 'width', config.width);
}
if (isPresent(config.height)) {
DOM.setStyle(dialogElement, 'height', config.height);
}
dialogRef.containerRef = containerRef;
// Now load the given component into the MdDialogContainer.
return this.componentLoader.loadNextToLocation(type, containerRef.instance.contentRef,
bindings)
.then((contentRef: ComponentRef) => {
// Wrap both component refs for the container and the content so that we can return
// the `instance` of the content but the dispose method of the container back to the
// opener.
dialogRef.contentRef = contentRef;
containerRef.instance.dialogRef = dialogRef;
backdropRefPromise.then((backdropRef: ComponentRef) => {
dialogRef.whenClosed.then((_) => { backdropRef.dispose(); });
});
return dialogRef;
});
});
}
/** Loads the dialog backdrop (transparent overlay over the rest of the page). */
_openBackdrop(elementRef: ElementRef, bindings: ResolvedProvider[]): Promise<ComponentRef> {
return this.componentLoader.loadNextToLocation(MdBackdrop, elementRef, bindings)
.then((componentRef: ComponentRef) => {
// TODO(tbosch): clean this up when we have custom renderers
// (https://github.com/angular/angular/issues/1807)
var backdropElement = componentRef.location.nativeElement;
DOM.addClass(backdropElement, 'md-backdrop');
DOM.appendChild(DOM.query('body'), backdropElement);
return componentRef;
});
}
alert(message: string, okMessage: string): Promise<any> {
throw 'Not implemented';
}
confirm(message: string, okMessage: string, cancelMessage: string): Promise<any> {
throw 'Not implemented';
}
}
/**
* Reference to an opened dialog.
*/
@Injectable()
export class MdDialogRef {
// Reference to the MdDialogContainer component.
containerRef: ComponentRef;
// Reference to the Component loaded as the dialog content.
_contentRef: ComponentRef;
// Whether the dialog is closed.
isClosed: boolean;
// Deferred resolved when the dialog is closed. The promise for this deferred is publicly exposed.
whenClosedDeferred: PromiseCompleter<any>;
// Deferred resolved when the content ComponentRef is set. Only used internally.
contentRefDeferred: PromiseCompleter<any>;
constructor() {
this._contentRef = null;
this.containerRef = null;
this.isClosed = false;
this.contentRefDeferred = PromiseWrapper.completer();
this.whenClosedDeferred = PromiseWrapper.completer();
}
set contentRef(value: ComponentRef) {
this._contentRef = value;
this.contentRefDeferred.resolve(value);
}
/** Gets the component instance for the content of the dialog. */
get instance() {
if (isPresent(this._contentRef)) {
return this._contentRef.instance;
}
// The only time one could attempt to access this property before the value is set is if an
// access occurs during
// the constructor of the very instance they are trying to get (which is much more easily
// accessed as `this`).
throw "Cannot access dialog component instance *from* that component's constructor.";
}
/** Gets a promise that is resolved when the dialog is closed. */
get whenClosed(): Promise<any> {
return this.whenClosedDeferred.promise;
}
/** Closes the dialog. This operation is asynchronous. */
close(result: any = null) {
this.contentRefDeferred.promise.then((_) => {
if (!this.isClosed) {
this.isClosed = true;
this.containerRef.dispose();
this.whenClosedDeferred.resolve(result);
}
});
}
}
/** Confiuration for a dialog to be opened. */
export class MdDialogConfig {
width: string;
height: string;
constructor() {
// Default configuration.
this.width = null;
this.height = null;
}
}
/**
* Container for user-provided dialog content.
*/
@Component({
selector: 'md-dialog-container',
host: {
'class': 'md-dialog',
'tabindex': '0',
'(body:keydown)': 'documentKeypress($event)',
},
encapsulation: ViewEncapsulation.None,
templateUrl: 'package:angular2_material/src/components/dialog/dialog.html',
directives: [forwardRef(() => MdDialogContent)]
})
class MdDialogContainer {
// Ref to the dialog content. Used by the DynamicComponentLoader to load the dialog content.
contentRef: ElementRef;
// Ref to the open dialog. Used to close the dialog based on certain events.
dialogRef: MdDialogRef;
constructor() {
this.contentRef = null;
this.dialogRef = null;
}
wrapFocus() {
// Return the focus to the host element. Blocked on #1251.
}
documentKeypress(event: KeyboardEvent) {
if (event.keyCode == KeyCodes.ESCAPE) {
this.dialogRef.close();
}
}
}
/**
* Simple decorator used only to communicate an ElementRef to the parent MdDialogContainer as the
* location
* for where the dialog content will be loaded.
*/
@Directive({
selector: 'md-dialog-content',
})
class MdDialogContent {
constructor(@Host() @SkipSelf() dialogContainer: MdDialogContainer, elementRef: ElementRef) {
dialogContainer.contentRef = elementRef;
}
}
/** Component for the dialog "backdrop", a transparent overlay over the rest of the page. */
@Component({
selector: 'md-backdrop',
host: {
'(click)': 'onClick()',
},
template: '',
encapsulation: ViewEncapsulation.None
})
class MdBackdrop {
dialogRef: MdDialogRef;
constructor(dialogRef: MdDialogRef) {
this.dialogRef = dialogRef;
}
onClick() {
// TODO(jelbourn): Use MdDialogConfig to capture option for whether dialog should close on
// clicking outside.
this.dialogRef.close();
}
}

View File

@ -1,68 +0,0 @@
md-grid-list {
display: block;
position: relative;
}
md-grid-tile {
display: block;
position: absolute;
figure {
display: flex;
position: absolute;
align-items: center;
justify-content: center;
height: 100%;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: 0;
margin: 0;
}
// Headers & footers
md-grid-tile-header,
md-grid-tile-footer {
display: flex;
flex-direction: row;
align-items: center;
height: 48px;
color: #fff;
background: rgba(0, 0, 0, 0.18);
overflow: hidden;
// Positioning
position: absolute;
left: 0;
right: 0;
h3,
h4 {
font-weight: 400;
margin: 0 0 0 16px;
}
h3 {
font-size: 14px;
}
h4 {
font-size: 12px;
}
}
md-grid-tile-header {
top: 0;
}
md-grid-tile-footer {
bottom: 0;
}
}

View File

@ -1,9 +0,0 @@
<style>
md-grid-tile {
background: lightblue;
}
</style>
<div class="md-grid-list">
<ng-content></ng-content>
</div>

View File

@ -1,426 +0,0 @@
import {
Component,
ViewEncapsulation,
Host,
SkipSelf,
OnChanges,
OnDestroy,
AfterContentChecked
} from 'angular2/core';
import {ListWrapper} from 'angular2/src/facade/collection';
import {StringWrapper, isPresent, isString, NumberWrapper} from 'angular2/src/facade/lang';
import {Math} from 'angular2/src/facade/math';
// TODO(jelbourn): Set appropriate aria attributes for grid list elements.
// TODO(jelbourn): Animations.
// TODO(jelbourn): Conditional (responsive) column count / row size.
// TODO(jelbourn): Re-layout on window resize / media change (debounced).
// TODO(jelbourn): gridTileHeader and gridTileFooter.
/** Row height mode options. Use a static class b/c TypeScript enums are strictly number-based. */
class RowHeightMode {
static FIT = 'fit';
static FIXED = 'fixed';
static RATIO = 'ratio';
}
@Component({
selector: 'md-grid-list',
inputs: ['cols', 'rowHeight', 'gutterSize'],
templateUrl: 'package:angular2_material/src/components/grid_list/grid_list.html',
encapsulation: ViewEncapsulation.None
})
export class MdGridList implements AfterContentChecked {
/** Array of tiles that are being rendered. */
tiles: MdGridTile[];
/** Number of columns being rendered. */
_cols: number;
/** Number of rows being rendered (computed). */
rows: number;
/** Mode used to determine row heights. See RowHeightMode. */
rowHeightMode: string;
/** Fixed row height, as given by the user. Only used for 'fixed' mode. */
fixedRowHeight: string;
/** Ratio width:height given by user to determine row height. Only used for 'ratio' mode.*/
rowHeightRatio: number;
/** The amount of space between tiles. This will be something like '5px' or '2em'. */
gutterSize: string;
constructor() {
this.tiles = [];
this.rows = 0;
}
set cols(value: any) {
this._cols = isString(value) ? NumberWrapper.parseInt(value, 10) : <number>value;
}
get cols() {
return this._cols;
}
/** Set internal representation of row height from the user-provided value. */
set rowHeight(value) {
if (value === RowHeightMode.FIT) {
this.rowHeightMode = RowHeightMode.FIT;
} else if (StringWrapper.contains(value, ':')) {
let ratioParts = value.split(':');
if (ratioParts.length !== 2) {
throw `md-grid-list: invalid ratio given for row-height: "${value}"`;
}
this.rowHeightMode = RowHeightMode.RATIO;
this.rowHeightRatio =
NumberWrapper.parseFloat(ratioParts[0]) / NumberWrapper.parseFloat(ratioParts[1]);
} else {
this.rowHeightMode = RowHeightMode.FIXED;
this.fixedRowHeight = value;
}
}
ngAfterContentChecked() {
this.layoutTiles();
}
/** Computes and applies the size and position for all children grid tiles. */
layoutTiles() {
let tracker = new TileCoordinator(this.cols, this.tiles);
this.rows = tracker.rowCount;
for (let i = 0; i < this.tiles.length; i++) {
let pos = tracker.positions[i];
let tile = this.tiles[i];
tile.style = this.getTileStyle(tile, pos.row, pos.col);
}
}
/**
* Adds a tile to the grid-list.
* @param tile
*/
addTile(tile: MdGridTile) {
this.tiles.push(tile);
}
/**
* Removes a tile from the grid-list.
* @param tile
*/
removeTile(tile: MdGridTile) {
ListWrapper.remove(this.tiles, tile);
}
/**
* Computes the amount of space a single 1x1 tile would take up (width or height).
* Used as a basis for other calculations.
* @param sizePercent Percent of the total grid-list space that one 1x1 tile would take up.
* @param gutterFraction Fraction of the gutter size taken up by one 1x1 tile.
* @return The size of a 1x1 tile as an expression that can be evaluated via CSS calc().
*/
getBaseTileSize(sizePercent: number, gutterFraction: number): string {
// Take the base size percent (as would be if evenly dividing the size between cells),
// and then subtracting the size of one gutter. However, since there are no gutters on the
// edges, each tile only uses a fraction (gutterShare = numGutters / numCells) of the gutter
// size. (Imagine having one gutter per tile, and then breaking up the extra gutter on the
// edge evenly among the cells).
return `(${sizePercent}% - ( ${this.gutterSize} * ${gutterFraction} ))`;
}
/**
* Gets The horizontal or vertical position of a tile, e.g., the 'top' or 'left' property value.
* @param offset Number of tiles that have already been rendered in the row/column.
* @param baseSize Base size of a 1x1 tile (as computed in getBaseTileSize).
* @return Position of the tile as a CSS calc() expression.
*/
getTilePosition(baseSize: string, offset: number): string {
// The position comes the size of a 1x1 tile plus gutter for each previous tile in the
// row/column (offset).
return `calc( (${baseSize} + ${this.gutterSize}) * ${offset} )`;
}
/**
* Gets the actual size of a tile, e.g., width or height, taking rowspan or colspan into account.
* @param baseSize Base size of a 1x1 tile (as computed in getBaseTileSize).
* @param span The tile's rowspan or colspan.
* @return Size of the tile as a CSS calc() expression.
*/
getTileSize(baseSize: string, span: number): string {
return `calc( (${baseSize} * ${span}) + (${span - 1} * ${this.gutterSize}) )`;
}
/** Gets the style properties to be applied to a tile for the given row and column index. */
getTileStyle(tile: MdGridTile, rowIndex: number, colIndex: number): TileStyle {
// Percent of the available horizontal space that one column takes up.
let percentWidthPerTile = 100 / this.cols;
// Fraction of the vertical gutter size that each column takes up.
// For example, if there are 5 columns, each column uses 4/5 = 0.8 times the gutter width.
let gutterWidthFractionPerTile = (this.cols - 1) / this.cols;
// Base horizontal size of a column.
let baseTileWidth = this.getBaseTileSize(percentWidthPerTile, gutterWidthFractionPerTile);
// The width and horizontal position of each tile is always calculated the same way, but the
// height and vertical position depends on the rowMode.
let tileStyle = new TileStyle();
tileStyle.left = this.getTilePosition(baseTileWidth, colIndex);
tileStyle.width = this.getTileSize(baseTileWidth, tile.colspan);
if (this.rowHeightMode == RowHeightMode.FIXED) {
// In fixed mode, simply use the given row height.
tileStyle.top = this.getTilePosition(this.fixedRowHeight, rowIndex);
tileStyle.height = this.getTileSize(this.fixedRowHeight, tile.rowspan);
}
if (this.rowHeightMode == RowHeightMode.RATIO) {
let percentHeightPerTile = percentWidthPerTile / this.rowHeightRatio;
let baseTileHeight = this.getBaseTileSize(percentHeightPerTile, gutterWidthFractionPerTile);
// Use paddingTop and marginTop to maintain the given aspect ratio, as
// a percentage-based value for these properties is applied versus the *width* of the
// containing block. See http://www.w3.org/TR/CSS2/box.html#margin-properties
tileStyle.marginTop = this.getTilePosition(baseTileHeight, rowIndex);
tileStyle.paddingTop = this.getTileSize(baseTileHeight, tile.rowspan);
}
if (this.rowHeightMode == RowHeightMode.FIT) {
// Percent of the available vertical space that one row takes up.
let percentHeightPerTile = 100 / this.cols;
// Fraction of the horizontal gutter size that each column takes up.
let gutterHeightFractionPerTile = (this.rows - 1) / this.rows;
// Base vertical size of a column.
let baseTileHeight = this.getBaseTileSize(percentHeightPerTile, gutterHeightFractionPerTile);
tileStyle.top = this.getTilePosition(baseTileHeight, rowIndex);
tileStyle.height = this.getTileSize(baseTileHeight, tile.rowspan);
}
return tileStyle;
}
}
@Component({
selector: 'md-grid-tile',
inputs: ['rowspan', 'colspan'],
host: {
'role': 'listitem',
'[style.height]': 'style.height',
'[style.width]': 'style.width',
'[style.top]': 'style.top',
'[style.left]': 'style.left',
'[style.marginTop]': 'style.marginTop',
'[style.paddingTop]': 'style.paddingTop',
},
templateUrl: 'package:angular2_material/src/components/grid_list/grid_tile.html',
encapsulation: ViewEncapsulation.None
})
export class MdGridTile implements OnDestroy,
OnChanges {
gridList: MdGridList;
_rowspan: number;
_colspan: number;
style: TileStyle;
isRegisteredWithGridList: boolean;
constructor(@SkipSelf() @Host() gridList: MdGridList) {
this.gridList = gridList;
// Tiles default to 1x1, but rowspan and colspan can be changed via binding.
this.rowspan = 1;
this.colspan = 1;
this.style = new TileStyle();
}
set rowspan(value) {
this._rowspan = isString(value) ? NumberWrapper.parseInt(<any>value, 10) : <number>value;
}
get rowspan() {
return this._rowspan;
}
set colspan(value) {
this._colspan = isString(value) ? NumberWrapper.parseInt(<any>value, 10) : <number>value;
}
get colspan() {
return this._colspan;
}
/**
* Change handler invoked when bindings are resolved or when bindings have changed.
* Notifies grid-list that a re-layout is required.
*/
ngOnChanges(_) {
if (!this.isRegisteredWithGridList) {
this.gridList.addTile(this);
this.isRegisteredWithGridList = true;
}
}
/**
* Destructor function. Deregisters this tile from the containing grid-list.
*/
ngOnDestroy() {
this.gridList.removeTile(this);
}
}
/**
* Class for determining, from a list of tiles, the (row, col) position of each of those tiles
* in the grid. This is necessary (rather than just rendering the tiles in normal document flow)
* because the tiles can have a rowspan.
*
* The positioning algorithm greedily places each tile as soon as it encounters a gap in the grid
* large enough to accomodate it so that the tiles still render in the same order in which they
* are given.
*
* The basis of the algorithm is the use of an array to track the already placed tiles. Each
* element of the array corresponds to a column, and the value indicates how many cells in that
* column are already occupied; zero indicates an empty cell. Moving "down" to the next row
* decrements each value in the tracking array (indicating that the column is one cell closer to
* being free).
*/
class TileCoordinator {
// Tracking array (see class description).
tracker: number[];
// Index at which the search for the next gap will start.
columnIndex: number;
// The current row index.
rowIndex: number;
// The computed (row, col) position of each tile (the output).
positions: Position[];
constructor(numColumns: number, tiles: MdGridTile[]) {
this.columnIndex = 0;
this.rowIndex = 0;
this.tracker = ListWrapper.createFixedSize(numColumns);
ListWrapper.fill(this.tracker, 0);
this.positions = tiles.map(tile => this._trackTile(tile));
}
/** Gets the number of rows occupied by tiles. */
get rowCount() {
return this.rowIndex + 1;
}
_trackTile(tile: MdGridTile): Position {
if (tile.colspan > this.tracker.length) {
throw `Tile with colspan ${tile.colspan} is wider
than grid with cols="${this.tracker.length}".`
}
// Start index is inclusive, end index is exclusive.
let gapStartIndex = -1;
let gapEndIndex = -1;
// Look for a gap large enough to fit the given tile. Empty spaces are marked with a zero.
do {
// If we've reached the end of the row, go to the next row
if (this.columnIndex + tile.colspan > this.tracker.length) {
this._nextRow();
continue;
}
gapStartIndex = ListWrapper.indexOf(this.tracker, 0, this.columnIndex);
// If there are no more empty spaces in this row at all, move on to the next row.
if (gapStartIndex == -1) {
this._nextRow();
continue;
}
gapEndIndex = this._findGapEndIndex(gapStartIndex);
// If a gap large enough isn't found, we want to start looking immediately after the current
// gap on the next iteration.
this.columnIndex = gapStartIndex + 1;
// Continue iterating until we find a gap wide enough for this tile.
} while (gapEndIndex - gapStartIndex < tile.colspan);
// We now have a space big enough for this tile, so place it.
this._markTilePosition(gapStartIndex, tile);
// The next time we look for a gap, the search will start at columnIndex, which should be
// immediately after the tile that has just been placed.
this.columnIndex = gapStartIndex + tile.colspan;
return new Position(this.rowIndex, gapStartIndex);
}
/** Move "down" to the next row. */
_nextRow() {
this.columnIndex = 0;
this.rowIndex++;
// Decrement all spaces by one to reflect moving down one row.
for (let i = 0; i < this.tracker.length; i++) {
this.tracker[i] = Math.max(0, this.tracker[i] - 1);
}
}
/**
* Finds the end index (exclusive) of a gap given the index from which to start looking.
* The gap ends when a non-zero value is found.
*/
_findGapEndIndex(gapStartIndex: number): number {
for (let i = gapStartIndex + 1; i < this.tracker.length; i++) {
if (this.tracker[i] != 0) {
return i;
}
}
// The gap ends with the end of the row.
return this.tracker.length;
}
/** Update the tile tracker to account for the given tile in the given space. */
_markTilePosition(start, tile) {
for (let i = 0; i < tile.colspan; i++) {
this.tracker[start + i] = tile.rowspan;
}
}
}
/** Simple data structure for tile position (row, col). */
class Position {
row: number;
col: number;
constructor(row: number, col: number) {
this.row = row;
this.col = col;
}
}
/** Simple data structure for style values to be applied to a tile. */
class TileStyle {
height: string;
width: string;
top: string;
left: string;
marginTop: string;
paddingTop: string;
}

View File

@ -1,5 +0,0 @@
<style>@import "package:angular2_material/src/components/grid_list/grid-list.css";</style>
<figure>
<ng-content></ng-content>
</figure>

View File

@ -1,257 +0,0 @@
@import "../../core/style/variables";
// TODO(jelbourn): This goes away.
@import "../../core/style/default-theme";
@mixin input-placeholder-color($color) {
&::-webkit-input-placeholder,
&::-moz-placeholder, /* Firefox 19+ */
&:-moz-placeholder, /* Firefox 18- */
&:-ms-input-placeholder {
color: $color;
}
}
$input-container-padding: 2px !default;
$input-label-default-offset: 24px !default;
$input-label-default-scale: 1.0 !default;
$input-label-float-offset: 4px !default;
$input-label-float-scale: 0.75 !default;
$input-placeholder-offset: $input-label-default-offset !default;
$input-border-width-default: 1px !default;
$input-border-width-focused: 2px !default;
$input-line-height: 26px !default;
$input-padding-top: 2px !default;
$input-error-font-size: 12px !default;
$input-error-height: 24px !default;
md-input-container {
box-sizing: border-box;
display: flex;
position: relative;
flex-direction: column;
overflow-x: hidden;
padding: $input-container-padding;
padding-bottom: $input-container-padding + $input-error-height;
> md-icon {
position: absolute;
top: 5px;
left: 2px;
+ input {
margin-left: 28px * 2;
}
}
textarea,
input[type="text"],
input[type="password"],
input[type="datetime"],
input[type="datetime-local"],
input[type="date"],
input[type="month"],
input[type="time"],
input[type="week"],
input[type="number"],
input[type="email"],
input[type="url"],
input[type="search"],
input[type="tel"],
input[type="color"] {
// Remove default appearance from all input / textarea.
// `appearance` is not supported in IE, but does IE apply any txt input styling?
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
}
textarea {
resize: none;
overflow: hidden;
}
textarea.md-input {
min-height: 2 * $input-line-height + $input-border-width-focused + $input-padding-top;
-ms-flex-preferred-size: auto; // IE10
}
label:not(.md-no-float),
.md-placeholder:not(.md-select-label) {
order: 1;
pointer-events: none;
-webkit-font-smoothing: antialiased;
padding-left: $input-container-padding;
z-index: 1;
transform: translate3d(0, $input-label-default-offset, 0) scale($input-label-default-scale);
transform-origin: left top;
transition: transform $swift-ease-out-timing-function 0.25s;
}
.md-placeholder:not(.md-select-label) {
position: absolute;
top: 0;
opacity: 0;
transition-property: opacity, transform;
transform: translate3d(0, $input-placeholder-offset + $baseline-grid * 0.75, 0);
}
&.md-input-focused .md-placeholder {
opacity: 1;
transform: translate3d(0, $input-placeholder-offset, 0);
}
// Placeholder should immediately disappear when the user starts typing
&.md-input-has-value .md-placeholder {
transition: none;
opacity: 0;
}
&:not( .md-input-has-value ) input:not( :focus ) {
color: transparent;
}
/*
* The .md-input class is added to the input/textarea
*/
.md-input {
flex: 1 1 auto;
order: 2;
display: block;
background: none;
padding: $input-padding-top 2px $input-border-width-focused - $input-border-width-default;
border-width: 0 0 $input-border-width-default 0;
line-height: $input-line-height;
-ms-flex-preferred-size: $input-line-height; // IE10
border-radius: 0;
&:focus {
outline: none;
}
&:invalid {
outline: none;
box-shadow: none;
}
}
.md-char-counter {
-webkit-font-smoothing: antialiased;
position: absolute;
font-size: $input-error-font-size;
line-height: $input-error-height;
bottom: $input-container-padding;
right: $input-container-padding;
// TODO(jelbourn): animations here.
}
&.md-input-focused,
&.md-input-has-value {
label:not(.md-no-float) {
transform: translate3d(0,$input-label-float-offset,0) scale($input-label-float-scale);
}
}
// Use wide border in error state or in focused state
&.md-input-focused .md-input {
padding-bottom: 0; // Increase border width by 1px, decrease padding by 1
border-width: 0 0 $input-border-width-focused 0;
}
.md-input {
&[disabled],
[disabled] & {
background-position: 0 bottom;
// This background-size is coordinated with a linear-gradient set in input-theme.scss
// to create a dotted line under the input.
background-size: 3px 1px;
background-repeat: repeat-x;
}
}
}
// THEME
md-input-container {
.md-input {
@include input-placeholder-color(md-color($md-foreground, hint-text));
color: md-color($md-foreground, text);
border-color: md-color($md-foreground, divider);
// text-shadow: md-color($md-foreground, shadow); // what is this?
}
> md-icon {
color: md-color($md-foreground, text);
}
label,
.md-placeholder {
// text-shadow: md-color($md-foreground, shadow); // what is this?
color: md-color($md-foreground, hint-text);
}
div[ng-messages] {
color: md-color($md-warn, 500)
}
&:not(.md-input-invalid) {
&.md-input-has-value {
label {
color: md-color($md-foreground, secondary-text);
}
}
&.md-input-focused {
.md-input {
border-color: md-color($md-primary, 500);
}
label {
color: md-color($md-primary, 500);
}
md-icon {
color: md-color($md-primary, 500);
}
&.md-accent {
.md-input {
border-color: md-color($md-accent, 500);
}
label {
color: md-color($md-accent, 500);
}
}
&.md-warn {
.md-input {
border-color: md-color($md-warn, 500);
}
label {
color: md-color($md-warn, 500);
}
}
}
}
&.md-input-invalid {
.md-input {
border-color: md-color($md-warn, 500);
}
label {
color: md-color($md-warn, 500);
}
.md-char-counter {
color: md-color($md-warn, 500);
}
}
.md-input {
&[disabled],
[disabled] & {
border-bottom-color: transparent;
color: md-color($md-foreground, disabled-text);
background-image: linear-gradient(to right, md-color($md-foreground, divider) 0%, md-color($md-foreground, divider) 33%, transparent 0%);
background-image: -ms-linear-gradient(left, transparent 0%, md-color($md-foreground, divider) 100%);
}
}
}

View File

@ -1,94 +0,0 @@
import {Directive, Attribute, Host, SkipSelf, AfterContentChecked} from 'angular2/core';
import {ObservableWrapper, EventEmitter} from 'angular2/src/facade/async';
// TODO(jelbourn): validation (will depend on Forms API).
// TODO(jelbourn): textarea resizing
// TODO(jelbourn): max-length counter
// TODO(jelbourn): placeholder property
@Directive({
selector: 'md-input-container',
host: {
'[class.md-input-has-value]': 'inputHasValue',
'[class.md-input-focused]': 'inputHasFocus',
}
})
export class MdInputContainer implements AfterContentChecked {
// The MdInput or MdTextarea inside of this container.
_input: MdInput;
// Whether the input inside of this container has a non-empty value.
inputHasValue: boolean;
// Whether the input inside of this container has focus.
inputHasFocus: boolean;
constructor(@Attribute('id') id: string) {
this._input = null;
this.inputHasValue = false;
this.inputHasFocus = false;
}
ngAfterContentChecked() {
// Enforce that this directive actually contains a text input.
if (this._input == null) {
throw 'No <input> or <textarea> found inside of <md-input-container>';
}
}
/** Registers the child MdInput or MdTextarea. */
registerInput(input) {
if (this._input != null) {
throw 'Only one text input is allowed per <md-input-container>.';
}
this._input = input;
this.inputHasValue = input.value != '';
// Listen to input changes and focus events so that we can apply the appropriate CSS
// classes based on the input state.
ObservableWrapper.subscribe(input.mdChange, value => { this.inputHasValue = value != ''; });
ObservableWrapper.subscribe<boolean>(input.mdFocusChange,
hasFocus => this.inputHasFocus = hasFocus);
}
}
@Directive({
selector: 'md-input-container input',
outputs: ['mdChange', 'mdFocusChange'],
host: {
'class': 'md-input',
'(input)': 'updateValue($event)',
'(focus)': 'setHasFocus(true)',
'(blur)': 'setHasFocus(false)'
}
})
export class MdInput {
value: string;
// Events emitted by this directive. We use these special 'md-' events to communicate
// to the parent MdInputContainer.
mdChange: EventEmitter<any>;
mdFocusChange: EventEmitter<any>;
constructor(@Attribute('value') value: string, @SkipSelf() @Host() container: MdInputContainer,
@Attribute('id') id: string) {
this.value = value == null ? '' : value;
this.mdChange = new EventEmitter();
this.mdFocusChange = new EventEmitter();
container.registerInput(this);
}
updateValue(event) {
this.value = event.target.value;
ObservableWrapper.callEmit(this.mdChange, this.value);
}
setHasFocus(hasFocus: boolean) {
ObservableWrapper.callEmit(this.mdFocusChange, hasFocus);
}
}

View File

@ -1,11 +0,0 @@
<div class="md-spinner-wrapper">
<div class="md-inner">
<div class="md-gap"></div>
<div class="md-left">
<div class="md-half-circle"></div>
</div>
<div class="md-right">
<div class="md-half-circle"></div>
</div>
</div>
</div>

View File

@ -1,10 +0,0 @@
import {Component, ViewEncapsulation} from 'angular2/core';
@Component({
selector: 'md-progress-circular',
templateUrl: 'package:angular2_material/src/components/progress-circular/progress_circular.html',
encapsulation: ViewEncapsulation.None
})
export class MdProgressCircular {
constructor() {}
}

View File

@ -1,9 +0,0 @@
<style>@import "package:angular2_material/src/components/progress-linear/progress_linear.css";</style>
<div class="md-progress-linear-container md-ready">
<div class="md-progress-linear-dashed"></div>
<div class="md-progress-linear-bar md-progress-linear-bar1"
[style.transform]="secondaryBarTransform"></div>
<div class="md-progress-linear-bar md-progress-linear-bar2"
[style.transform]="primaryBarTransform"></div>
</div>

View File

@ -1,266 +0,0 @@
@import "../../core/style/variables";
// TODO(jelbourn): This goes away.
@import "../../core/style/default-theme";
$progress-linear-bar-height: 5px !default;
md-progress-linear {
display: block;
width: 100%;
height: $progress-linear-bar-height;
*, *:before {
box-sizing: border-box;
}
.md-progress-linear-container {
overflow: hidden;
position: relative;
height: $progress-linear-bar-height;
top: $progress-linear-bar-height;
transform: translate(0, 5px) scale(1, 0);
transition: all .3s linear;
}
.md-progress-linear-container.md-ready {
transform: translate(0, 0) scale(1, 1);
}
.md-progress-linear-bar {
height: $progress-linear-bar-height;
position: absolute;
width: 100%;
}
.md-progress-linear-bar1, .md-progress-linear-bar2 {
transition: all 0.2s linear;
}
&[md-mode="determinate"] {
.md-progress-linear-bar1 {
display: none;
}
}
&[md-mode="indeterminate"] {
.md-progress-linear-bar1 {
animation: indeterminate1 4s infinite linear;
}
.md-progress-linear-bar2 {
animation: indeterminate2 4s infinite linear;
}
}
&[md-mode="buffer"] {
.md-progress-linear-container {
background-color: transparent !important;
}
.md-progress-linear-dashed:before {
content: "";
display: block;
height: $progress-linear-bar-height;
width: 100%;
margin-top: 0px;
position: absolute;
background-color: transparent;
background-size: 10px 10px !important;
background-position: 0px -23px;
animation: buffer 3s infinite linear;
}
}
&[md-mode="query"] {
.md-progress-linear-bar2 {
animation: query .8s infinite cubic-bezier(0.390, 0.575, 0.565, 1.000);
}
}
}
@keyframes indeterminate1 {
0% {
transform: translateX(-25%) scale(.5, 1);
}
10% {
transform: translateX(25%) scale(.5, 1);
}
19.99% {
transform: translateX(50%) scale(0, 1);
}
20% {
transform: translateX(-37.5%) scale(.25, 1);
}
30% {
transform: translateX(37.5%) scale(.25, 1);
}
34.99% {
transform: translateX(50%) scale(0, 1);
}
36.99% {
transform: translateX(50%) scale(0, 1);
}
37% {
transform: translateX(-37.5%) scale(.25, 1);
}
47% {
transform: translateX(20%) scale(.25, 1);
}
52% {
transform: translateX(35%) scale(.05, 1);
}
55% {
transform: translateX(35%) scale(.1, 1);
}
58% {
transform: translateX(50%) scale(.1, 1);
}
61.99% {
transform: translateX(50%) scale(0, 1);
}
69.99% {
transform: translateX(50%) scale(0, 1);
}
70% {
transform: translateX(-37.5%) scale(.25, 1);
}
80% {
transform: translateX(20%) scale(.25, 1);
}
85% {
transform: translateX(35%) scale(.05, 1);
}
88% {
transform: translateX(35%) scale(.1, 1);
}
91% {
transform: translateX(50%) scale(.1, 1);
}
92.99% {
transform: translateX(50%) scale(0, 1);
}
93% {
transform: translateX(-50%) scale(0, 1);
}
100% {
transform: translateX(-25%) scale(.5, 1);
}
}
@keyframes indeterminate2 {
0% {
transform: translateX(-50%) scale(0, 1);
}
25.99%{
transform: translateX(-50%) scale(0, 1);
}
28% {
transform: translateX(-37.5%) scale(.25, 1);
}
38% {
transform: translateX(37.5%) scale(.25, 1);
}
42.99% {
transform: translateX(50%) scale(0, 1);
}
46.99% {
transform: translateX(50%) scale(0, 1);
}
49.99% {
transform: translateX(50%) scale(0, 1);
}
50% {
transform: translateX(-50%) scale(0, 1);
}
60% {
transform: translateX(-25%) scale(.5, 1);
}
70% {
transform: translateX(25%) scale(.5, 1);
}
79.99% {
transform: translateX(50%) scale(0, 1);
}
}
@keyframes query {
0% {
opacity: 1;
transform: translateX(35%) scale(.3, 1);
}
100% {
opacity: 0;
transform: translateX(-50%) scale(0, 1);
}
}
@keyframes buffer {
0% {
opacity: 1;
background-position: 0px -23px;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
background-position: -200px -23px;
}
}
// THEME
md-progress-linear {
.md-progress-linear-container {
background-color: md-color($md-primary, 100);
}
.md-progress-linear-bar {
background-color: md-color($md-primary);
}
&.md-warn .md-progress-linear-container {
background-color: md-color($md-warn, 100);
}
&.md-warn .md-progress-linear-bar {
background-color: md-color($md-warn);
}
&.md-accent .md-progress-linear-container {
background-color: md-color($md-accent, 100);
}
&.md-accent .md-progress-linear-bar {
background-color: md-color($md-accent);
}
&[md-mode=buffer] {
&.md-primary {
.md-progress-linear-bar1 {
background-color: md-color($md-primary, 100);
}
.md-progress-linear-dashed:before {
background: radial-gradient(md-color($md-primary, 100) 0%, md-color($md-primary, 100) 16%, transparent 42%);
}
}
&.md-warn {
.md-progress-linear-bar1 {
background-color: md-color($md-warn, 100);
}
.md-progress-linear-dashed:before {
background: radial-gradient(md-color($md-warn, 100) 0%, md-color($md-warn, 100) 16%, transparent 42%);
}
}
&.md-accent {
.md-progress-linear-bar1 {
background-color: md-color($md-accent, 100);
}
.md-progress-linear-dashed:before {
background: radial-gradient(md-color($md-accent, 100) 0%, md-color($md-accent, 100) 16%, transparent 42%);
}
}
}
}

View File

@ -1,88 +0,0 @@
import {Component, ViewEncapsulation, Attribute, OnChanges} from 'angular2/core';
import {CONST} from 'angular2/src/facade/lang';
import {isPresent, isBlank} from 'angular2/src/facade/lang';
import {Math} from 'angular2/src/facade/math';
/** Different display / behavior modes for progress-linear. */
@CONST()
class ProgressMode {
@CONST() static DETERMINATE = 'determinate';
@CONST() static INDETERMINATE = 'indeterminate';
@CONST() static BUFFER = 'buffer';
@CONST() static QUERY = 'query';
}
@Component({
selector: 'md-progress-linear',
inputs: ['value', 'bufferValue'],
host: {
'role': 'progressbar',
'aria-valuemin': '0',
'aria-valuemax': '100',
'[attr.aria-valuenow]': 'value'
},
templateUrl: 'package:angular2_material/src/components/progress-linear/progress_linear.html',
directives: [],
encapsulation: ViewEncapsulation.None
})
export class MdProgressLinear implements OnChanges {
/** Value for the primary bar. */
value_: number;
/** Value for the secondary bar. */
bufferValue: number;
/** The render mode for the progress bar. */
mode: string;
/** CSS `transform` property applied to the primary bar. */
primaryBarTransform: string;
/** CSS `transform` property applied to the secondary bar. */
secondaryBarTransform: string;
constructor(@Attribute('mode') mode: string) {
this.primaryBarTransform = '';
this.secondaryBarTransform = '';
this.mode = isPresent(mode) ? mode : ProgressMode.DETERMINATE;
}
get value() {
return this.value_;
}
set value(v) {
if (isPresent(v)) {
this.value_ = MdProgressLinear.clamp(v);
}
}
ngOnChanges(_) {
// If the mode does not use a value, or if there is no value, do nothing.
if (this.mode == ProgressMode.QUERY || this.mode == ProgressMode.INDETERMINATE ||
isBlank(this.value)) {
return;
}
this.primaryBarTransform = this.transformForValue(this.value);
// The bufferValue is only used in buffer mode.
if (this.mode == ProgressMode.BUFFER) {
this.secondaryBarTransform = this.transformForValue(this.bufferValue);
}
}
/** Gets the CSS `transform` property for a progress bar based on the given value (0 - 100). */
transformForValue(value) {
// TODO(jelbourn): test perf gain of caching these, since there are only 101 values.
let scale = value / 100;
let translateX = (value - 100) / 2;
return `translateX(${translateX}%) scale(${scale}, 1)`;
}
/** Clamps a value to be between 0 and 100. */
static clamp(v) {
return Math.max(0, Math.min(100, v));
}
}

View File

@ -1,141 +0,0 @@
@import "../../core/style/variables";
@import "../../core/style/shadows";
// TODO(jelbourn): This goes away.
@import "../../core/style/default-theme";
$radio-width: 16px !default;
$radio-height: $radio-width !default;
md-radio-button {
display: block;
margin: 15px;
white-space: nowrap;
cursor: pointer;
}
md-radio-group {
border: 1px dotted transparent;
display: inline-block;
outline: none;
}
.md-radio-container {
box-sizing: border-box;
position: relative;
top: 4px;
display: inline-block;
width: $radio-width;
height: $radio-width;
cursor: pointer;
}
.md-radio-off {
box-sizing: border-box;
position: absolute;
top: 0;
left: 0;
width: $radio-width;
height: $radio-width;
border: solid 2px;
border-radius: 50%;
transition: border-color ease 0.28s;
}
.md-radio-on {
box-sizing: border-box;
position: absolute;
top: 0;
left: 0;
width: $radio-width;
height: $radio-width;
border-radius: 50%;
transition: transform ease 0.28s;
transform: scale(0);
.md-radio-checked & {
transform: scale(0.55);
}
}
// This is the style applied to the content (included via <ng-content>). If we could rely on shadow
// DOM always being present, this would use the ::content psuedo-class.
.md-radio-label {
position: relative;
display: inline-block;
margin-left: 10px;
margin-right: 10px;
vertical-align: middle;
white-space: normal;
// pointer-events: none; ???
width: auto;
}
.md-radio-root {
display: block;
cursor: pointer;
}
// THEME
.md-radio-off {
border-color: md-color($md-foreground, icon);
}
.md-radio-on {
background-color: md-color($md-accent, 0.87);
}
.md-radio-checked .md-radio-off {
border-color: md-color($md-accent, 0.87);
}
// TODO
.md-radio-checked .md-ink-ripple { }
.md-radio-container .md-ripple { }
p
md-radio-group:not([disabled]) md-radio:not([disabled]) {
&.md-primary {
.md-radio-on {
background-color: md-color($md-primary, 0.87);
}
&.md-radio-checked .md-radio-off {
border-color: md-color($md-primary, 0.87);
}
&.md-radio-checked .md-ink-ripple {
color: md-color($md-primary, 0.87);
}
.md-radio-container .md-ripple {
color: md-color($md-primary, 600);
}
}
&.md-warn {
.md-radio-on {
background-color: md-color($md-warn, 0.87);
}
&.md-radio-checked .md-radio-off {
border-color: md-color($md-warn, 0.87);
}
&.md-radio-checked .md-ink-ripple {
color: md-color($md-warn, 0.87);
}
.md-radio-container .md-ripple {
color: md-color($md-warn, 600);
}
}
}
md-radio-button[disabled],
md-radio-group[disabled] md-radio-button {
.md-radio-container .md-radio-off,
.md-radio-container .md-radio-on {
border-color: md-color($md-foreground, disabled);
}
}

View File

@ -1,5 +0,0 @@
md-radio-group {
border: 1px dotted transparent;
display: block;
outline: none;
}

View File

@ -1,18 +0,0 @@
<style>@import "package:angular2_material/src/components/radio/radio-button.css";</style>
<!-- TODO(jelbourn): render the radio on either side of the content -->
<label role="radio" class="md-radio-root"
[class.md-radio-checked]="checked"
(click)="select($event)">
<!-- The actual `radio` part of the control. -->
<div class="md-radio-container">
<div class="md-radio-off"></div>
<div class="md-radio-on"></div>
</div>
<!-- The label for radio control. -->
<div class="md-radio-label">
<ng-content></ng-content>
</div>
</label>

View File

@ -1,308 +0,0 @@
import {
Component,
ViewEncapsulation,
Host,
SkipSelf,
Attribute,
Optional,
OnChanges,
OnInit
} from 'angular2/core';
import {isPresent, StringWrapper, NumberWrapper} from 'angular2/src/facade/lang';
import {ObservableWrapper, EventEmitter} from 'angular2/src/facade/async';
import {Event, KeyboardEvent} from 'angular2/src/facade/browser';
import {MdRadioDispatcher} from 'angular2_material/src/components/radio/radio_dispatcher';
import {KeyCodes} from 'angular2_material/src/core/key_codes';
// TODO(jelbourn): Behaviors to test
// Disabled radio don't select
// Disabled radios don't propagate click event
// Radios are disabled by parent group
// Radios set default tab index iff not in parent group
// Radios are unique-select
// Radio updates parent group's value
// Change to parent group's value updates the selected child radio
// Radio name is pulled on parent group
// Radio group changes on arrow keys
// Radio group skips disabled radios on arrow keys
var _uniqueIdCounter: number = 0;
@Component({
selector: 'md-radio-group',
outputs: ['change'],
inputs: ['disabled', 'value'],
host: {
'role': 'radiogroup',
'[attr.aria-disabled]': 'disabled',
'[attr.aria-activedescendant]': 'activedescendant',
// TODO(jelbourn): Remove ^ when event retargeting is fixed.
'(keydown)': 'onKeydown($event)',
'[tabindex]': 'tabindex',
},
templateUrl: 'package:angular2_material/src/components/radio/radio_group.html',
encapsulation: ViewEncapsulation.None
})
export class MdRadioGroup implements OnChanges {
/** The selected value for the radio group. The value comes from the options. */
value: any;
/** The HTML name attribute applied to radio buttons in this group. */
name_: string;
/** Dispatcher for coordinating radio unique-selection by name. */
radioDispatcher: MdRadioDispatcher;
/** Array of child radio buttons. */
radios_: MdRadioButton[];
activedescendant: any;
disabled_: boolean;
/** The ID of the selected radio button. */
selectedRadioId: string;
change: EventEmitter<any>;
tabindex: number;
constructor(@Attribute('tabindex') tabindex: string, @Attribute('disabled') disabled: string,
radioDispatcher: MdRadioDispatcher) {
this.name_ = `md-radio-group-${_uniqueIdCounter++}`;
this.radios_ = [];
this.change = new EventEmitter();
this.radioDispatcher = radioDispatcher;
this.selectedRadioId = '';
this.disabled_ = false;
// The simple presence of the `disabled` attribute dictates disabled state.
this.disabled = isPresent(disabled);
// If the user has not set a tabindex, default to zero (in the normal document flow).
this.tabindex = isPresent(tabindex) ? NumberWrapper.parseInt(tabindex, 10) : 0;
}
/** Gets the name of this group, as to be applied in the HTML 'name' attribute. */
getName(): string {
return this.name_;
}
get disabled() {
return this.disabled_;
}
set disabled(value) {
this.disabled_ = isPresent(value) && value !== false;
}
/** Change handler invoked when bindings are resolved or when bindings have changed. */
ngOnChanges(_) {
// If the component has a disabled attribute with no value, it will set disabled = ''.
this.disabled = isPresent(this.disabled) && this.disabled !== false;
// If the value of this radio-group has been set or changed, we have to look through the
// child radio buttons and select the one that has a corresponding value (if any).
if (isPresent(this.value) && this.value != '') {
this.radioDispatcher.notify(this.name_);
this.radios_.forEach(radio => {
if (radio.value == this.value) {
radio.checked = true;
this.selectedRadioId = radio.id;
this.activedescendant = radio.id;
}
});
}
}
/** Update the value of this radio group from a child md-radio being selected. */
updateValue(value: any, id: string) {
this.value = value;
this.selectedRadioId = id;
this.activedescendant = id;
ObservableWrapper.callEmit(this.change, null);
}
/** Registers a child radio button with this group. */
register(radio: MdRadioButton) {
this.radios_.push(radio);
}
/** Handles up and down arrow key presses to change the selected child radio. */
onKeydown(event: KeyboardEvent) {
if (this.disabled) {
return;
}
switch (event.keyCode) {
case KeyCodes.UP:
this.stepSelectedRadio(-1);
event.preventDefault();
break;
case KeyCodes.DOWN:
this.stepSelectedRadio(1);
event.preventDefault();
break;
}
}
// TODO(jelbourn): Replace this with a findIndex method in the collections facade.
getSelectedRadioIndex(): number {
for (let i = 0; i < this.radios_.length; i++) {
if (this.radios_[i].id == this.selectedRadioId) {
return i;
}
}
return -1;
}
/** Steps the selected radio based on the given step value (usually either +1 or -1). */
stepSelectedRadio(step) {
let index = this.getSelectedRadioIndex() + step;
if (index < 0 || index >= this.radios_.length) {
return;
}
let radio = this.radios_[index];
// If the next radio is line is disabled, skip it (maintaining direction).
if (radio.disabled) {
this.stepSelectedRadio(step + (step < 0 ? -1 : 1));
return;
}
this.radioDispatcher.notify(this.name_);
radio.checked = true;
ObservableWrapper.callEmit(this.change, null);
this.value = radio.value;
this.selectedRadioId = radio.id;
this.activedescendant = radio.id;
}
}
@Component({
selector: 'md-radio-button',
inputs: ['id', 'name', 'value', 'checked', 'disabled'],
host: {
'role': 'radio',
'[id]': 'id',
'[tabindex]': 'tabindex',
'[attr.aria-checked]': 'checked',
'[attr.aria-disabled]': 'disabled',
'(keydown)': 'onKeydown($event)',
},
templateUrl: 'package:angular2_material/src/components/radio/radio_button.html',
directives: [],
encapsulation: ViewEncapsulation.None
})
export class MdRadioButton implements OnInit {
/** Whether this radio is checked. */
checked: boolean;
/** Whether the radio is disabled. */
disabled_: boolean;
/** The unique ID for the radio button. */
id: string;
/** Analog to HTML 'name' attribute used to group radios for unique selection. */
name: string;
/** Value assigned to this radio. Used to assign the value to the parent MdRadioGroup. */
value: any;
/** The parent radio group. May or may not be present. */
radioGroup: MdRadioGroup;
/** Dispatcher for coordinating radio unique-selection by name. */
radioDispatcher: MdRadioDispatcher;
tabindex: number;
constructor(@Optional() @SkipSelf() @Host() radioGroup: MdRadioGroup, @Attribute('id') id: string,
@Attribute('tabindex') tabindex: string, radioDispatcher: MdRadioDispatcher) {
// Assertions. Ideally these should be stripped out by the compiler.
// TODO(jelbourn): Assert that there's no name binding AND a parent radio group.
this.radioGroup = radioGroup;
this.radioDispatcher = radioDispatcher;
this.value = null;
this.checked = false;
this.id = isPresent(id) ? id : `md-radio-${_uniqueIdCounter++}`;
// Whenever a radio button with the same name is checked, uncheck this radio button.
radioDispatcher.listen((name) => {
if (name == this.name) {
this.checked = false;
}
});
// When this radio-button is inside of a radio-group, the group determines the name.
if (isPresent(radioGroup)) {
this.name = radioGroup.getName();
this.radioGroup.register(this);
}
// If the user has not set a tabindex, default to zero (in the normal document flow).
if (!isPresent(radioGroup)) {
this.tabindex = isPresent(tabindex) ? NumberWrapper.parseInt(tabindex, 10) : 0;
} else {
this.tabindex = -1;
}
}
/** Change handler invoked when bindings are resolved or when bindings have changed. */
ngOnInit() {
if (isPresent(this.radioGroup)) {
this.name = this.radioGroup.getName();
}
}
/** Whether this radio button is disabled, taking the parent group into account. */
isDisabled(): boolean {
// Here, this.disabled may be true/false as the result of a binding, may be the empty string
// if the user just adds a `disabled` attribute with no value, or may be absent completely.
// TODO(jelbourn): If someone sets `disabled="disabled"`, will this work in dart?
return this.disabled || (isPresent(this.disabled) && StringWrapper.equals(this.disabled, '')) ||
(isPresent(this.radioGroup) && this.radioGroup.disabled);
}
get disabled(): any {
return this.disabled_;
}
set disabled(value: any) {
this.disabled_ = isPresent(value) && value !== false;
}
/** Select this radio button. */
select(event: Event) {
if (this.isDisabled()) {
event.stopPropagation();
return;
}
// Notifiy all radio buttons with the same name to un-check.
this.radioDispatcher.notify(this.name);
this.checked = true;
if (isPresent(this.radioGroup)) {
this.radioGroup.updateValue(this.value, this.id);
}
}
/** Handles pressing the space key to select this focused radio button. */
onKeydown(event: KeyboardEvent) {
if (event.keyCode == KeyCodes.SPACE) {
event.preventDefault();
this.select(event);
}
}
}

View File

@ -1,25 +0,0 @@
import {Injectable} from 'angular2/core';
/**
* Class for radio buttons to coordinate unique selection based on name.
* Indended to be consumed as an Angular service.
*/
@Injectable()
export class MdRadioDispatcher {
// TODO(jelbourn): Change this to TypeScript syntax when supported.
listeners_: Function[];
constructor() {
this.listeners_ = [];
}
/** Notify other radio buttons that selection for the given name has been set. */
notify(name: string) {
this.listeners_.forEach(listener => listener(name));
}
/** Listen for future changes to radio button selection. */
listen(listener) {
this.listeners_.push(listener);
}
}

View File

@ -1,2 +0,0 @@
<style>@import "package:angular2_material/src/components/radio/radio-group.css";</style>
<ng-content></ng-content>

View File

@ -1,11 +0,0 @@
<style>@import "package:angular2_material/src/components/switcher/switch.css";</style>
<div (click)="toggle($event)">
<div class="md-switch-container">
<div class="md-switch-bar"></div>
<div class="md-switch-thumb-container">
<div class="md-switch-thumb"></div>
</div>
</div>
<div class="md-switch-label"><ng-content></ng-content></div>
</div>

View File

@ -1,172 +0,0 @@
@import "../../core/style/variables";
// TODO(jelbourn): This goes away.
@import "../../core/style/default-theme";
$switch-width: 36px !default;
$switch-height: $baseline-grid * 3 !default;
$switch-bar-height: 14px !default;
$switch-thumb-size: 20px !default;
md-switch {
display: flex;
align-items: center;
margin: 15px;
white-space: nowrap;
cursor: pointer;
outline: none;
user-select: none;
* {
box-sizing: border-box;
}
.md-switch-container {
cursor: grab;
width: $switch-width;
height: $switch-height;
position: relative;
user-select: none;
margin-right: 8px;
}
// If the user moves his mouse off the switch, stil display grabbing cursor
&:not([disabled]) {
.md-switch-dragging,
&.md-switch-dragging .md-switch-container {
cursor: grabbing;
}
}
.md-switch-label {
border: 0 transparent;
}
.md-switch-bar {
left: 1px;
width: $switch-width - 2px;
top: $switch-height / 2 - $switch-bar-height / 2;
height: $switch-bar-height;
border-radius: 8px;
position: absolute;
}
.md-switch-thumb-container {
top: $switch-height / 2 - $switch-thumb-size / 2;
left: 0;
width: $switch-width - $switch-thumb-size;
position: absolute;
transform: translate3d(0,0,0);
z-index: 1;
}
&[aria-checked="true"] .md-switch-thumb-container {
transform: translate3d(100%, 0, 0);
}
.md-switch-thumb {
position: absolute;
margin: 0;
left: 0;
top: 0;
outline: none;
height: $switch-thumb-size;
width: $switch-thumb-size;
border-radius: 50%;
box-shadow: $whiteframe-shadow-z1;
// todo
.md-ripple-container {
position: absolute;
display: block;
width: auto;
height: auto;
left: -$switch-thumb-size;
top: -$switch-thumb-size;
right: -$switch-thumb-size;
bottom: -$switch-thumb-size;
}
}
&:not(.md-switch-dragging) {
.md-switch-bar,
.md-switch-thumb-container,
.md-switch-thumb {
transition: $swift-ease-in-out;
transition-property: transform, background-color;
}
.md-switch-bar,
.md-switch-thumb {
transition-delay: 0.05s;
}
}
}
// TODO(jelbourn): Why are these not defined in terms of the theme?
@media screen and (-ms-high-contrast: active) {
md-switch .md-switch-bar {
background-color: #666;
}
md-switch[aria-checked="true"] .md-switch-bar {
background-color: #9E9E9E;
}
md-switch.md-default-theme .md-switch-thumb {
background-color: #fff;
}
}
// THEME
md-switch {
.md-switch-thumb {
background-color: md-color($md-background, 50);
}
.md-switch-bar {
background-color: md-color($md-background, 500);
}
&[aria-checked="true"] {
.md-switch-thumb {
background-color: md-color($md-accent);
}
.md-switch-bar {
background-color: md-color($md-accent, 0.5);
}
&.md-primary {
.md-switch-thumb {
background-color: md-color($md-primary);
}
.md-switch-bar {
background-color: md-color($md-primary, 0.5);
}
}
&.md-warn {
.md-switch-thumb {
background-color: md-color($md-warn);
}
.md-switch-bar {
background-color: md-color($md-warn, 0.5);
}
}
}
&[disabled] {
.md-switch-thumb {
background-color: md-color($md-background, 400);
}
.md-switch-bar {
background-color: md-color($md-foreground, divider);
}
}
&:focus {
.md-switch-label:not(:empty) {
border: 1px dotted md-color($md-foreground, text);
}
}
}

View File

@ -1,24 +0,0 @@
import {Component, ViewEncapsulation, Attribute} from 'angular2/core';
import {MdCheckbox} from "../checkbox/checkbox";
// TODO(jelbourn): add gesture support
// TODO(jelbourn): clean up CSS.
@Component({
selector: 'md-switch',
inputs: ['checked', 'disabled'],
host: {
'role': 'checkbox',
'[attr.aria-checked]': 'checked',
'[attr.aria-disabled]': 'disabled_',
'(keydown)': 'onKeydown($event)',
},
templateUrl: 'package:angular2_material/src/components/switcher/switch.html',
directives: [],
encapsulation: ViewEncapsulation.None
})
export class MdSwitch extends MdCheckbox {
constructor(@Attribute('tabindex') tabindex: string) {
super(tabindex);
}
}

View File

@ -1,10 +0,0 @@
import {CONST} from 'angular2/src/facade/lang';
// Can't use an enum because Dart doesn't support enum initializers.
@CONST()
export class KeyCodes {
@CONST() static ESCAPE = 27;
@CONST() static SPACE = 32;
@CONST() static UP = 38;
@CONST() static DOWN = 40;
}

View File

@ -1,13 +0,0 @@
@import 'theme-functions';
@import 'palette';
// Person creating a theme writes variables like this:
$md-is-dark-theme: false;
$md-primary: md-palette($md-indigo, 500, 100, 700, $md-contrast-palettes);
$md-accent: md-palette($md-red, A200, A100, A400, $md-contrast-palettes);
$md-background: md-palette($md-grey, 500, 300, 600, $md-contrast-palettes);
$md-warn: md-palette($md-red, 500, 300, 800, $md-contrast-palettes);
$md-foreground: if($md-is-dark-theme, $md-dark-theme-foreground, $md-light-theme-foreground);

View File

@ -1,666 +0,0 @@
// Core color palettes.
$md-red: (
50: #ffebee,
100: #ffcdd2,
200: #ef9a9a,
300: #e57373,
400: #ef5350,
500: #f44336,
600: #e53935,
700: #d32f2f,
800: #c62828,
900: #b71c1c,
A100: #ff8a80,
A200: #ff5252,
A400: #ff1744,
A700: #d50000,
);
$md-pink: (
50: #fce4ec,
100: #f8bbd0,
200: #f48fb1,
300: #f06292,
400: #ec407a,
500: #e91e63,
600: #d81b60,
700: #c2185b,
800: #ad1457,
900: #880e4f,
A100: #ff80ab,
A200: #ff4081,
A400: #f50057,
A700: #c51162,
);
$md-purple: (
50: #f3e5f5,
100: #e1bee7,
200: #ce93d8,
300: #ba68c8,
400: #ab47bc,
500: #9c27b0,
600: #8e24aa,
700: #7b1fa2,
800: #6a1b9a,
900: #4a148c,
A100: #ea80fc,
A200: #e040fb,
A400: #d500f9,
A700: #aa00ff,
);
$md-deep-purple: (
50: #ede7f6,
100: #d1c4e9,
200: #b39ddb,
300: #9575cd,
400: #7e57c2,
500: #673ab7,
600: #5e35b1,
700: #512da8,
800: #4527a0,
900: #311b92,
A100: #b388ff,
A200: #7c4dff,
A400: #651fff,
A700: #6200ea,
);
$md-indigo: (
50: #e8eaf6,
100: #c5cae9,
200: #9fa8da,
300: #7986cb,
400: #5c6bc0,
500: #3f51b5,
600: #3949ab,
700: #303f9f,
800: #283593,
900: #1a237e,
A100: #8c9eff,
A200: #536dfe,
A400: #3d5afe,
A700: #304ffe,
);
$md-blue: (
50: #e3f2fd,
100: #bbdefb,
200: #90caf9,
300: #64b5f6,
400: #42a5f5,
500: #2196f3,
600: #1e88e5,
700: #1976d2,
800: #1565c0,
900: #0d47a1,
A100: #82b1ff,
A200: #448aff,
A400: #2979ff,
A700: #2962ff,
);
$md-light-blue: (
50: #e1f5fe,
100: #b3e5fc,
200: #81d4fa,
300: #4fc3f7,
400: #29b6f6,
500: #03a9f4,
600: #039be5,
700: #0288d1,
800: #0277bd,
900: #01579b,
A100: #80d8ff,
A200: #40c4ff,
A400: #00b0ff,
A700: #0091ea,
);
$md-cyan: (
50: #e0f7fa,
100: #b2ebf2,
200: #80deea,
300: #4dd0e1,
400: #26c6da,
500: #00bcd4,
600: #00acc1,
700: #0097a7,
800: #00838f,
900: #006064,
A100: #84ffff,
A200: #18ffff,
A400: #00e5ff,
A700: #00b8d4,
);
$md-teal: (
50: #e0f2f1,
100: #b2dfdb,
200: #80cbc4,
300: #4db6ac,
400: #26a69a,
500: #009688,
600: #00897b,
700: #00796b,
800: #00695c,
900: #004d40,
A100: #a7ffeb,
A200: #64ffda,
A400: #1de9b6,
A700: #00bfa5,
);
$md-green: (
50: #e8f5e9,
100: #c8e6c9,
200: #a5d6a7,
300: #81c784,
400: #66bb6a,
500: #4caf50,
600: #43a047,
700: #388e3c,
800: #2e7d32,
900: #1b5e20,
A100: #b9f6ca,
A200: #69f0ae,
A400: #00e676,
A700: #00c853,
);
$md-light-green: (
50: #f1f8e9,
100: #dcedc8,
200: #c5e1a5,
300: #aed581,
400: #9ccc65,
500: #8bc34a,
600: #7cb342,
700: #689f38,
800: #558b2f,
900: #33691e,
A100: #ccff90,
A200: #b2ff59,
A400: #76ff03,
A700: #64dd17,
);
$md-lime: (
50: #f9fbe7,
100: #f0f4c3,
200: #e6ee9c,
300: #dce775,
400: #d4e157,
500: #cddc39,
600: #c0ca33,
700: #afb42b,
800: #9e9d24,
900: #827717,
A100: #f4ff81,
A200: #eeff41,
A400: #c6ff00,
A700: #aeea00,
);
$md-yellow: (
50: #fffde7,
100: #fff9c4,
200: #fff59d,
300: #fff176,
400: #ffee58,
500: #ffeb3b,
600: #fdd835,
700: #fbc02d,
800: #f9a825,
900: #f57f17,
A100: #ffff8d,
A200: #ffff00,
A400: #ffea00,
A700: #ffd600,
);
$md-amber: (
50: #fff8e1,
100: #ffecb3,
200: #ffe082,
300: #ffd54f,
400: #ffca28,
500: #ffc107,
600: #ffb300,
700: #ffa000,
800: #ff8f00,
900: #ff6f00,
A100: #ffe57f,
A200: #ffd740,
A400: #ffc400,
A700: #ffab00,
);
$md-orange: (
50: #fff3e0,
100: #ffe0b2,
200: #ffcc80,
300: #ffb74d,
400: #ffa726,
500: #ff9800,
600: #fb8c00,
700: #f57c00,
800: #ef6c00,
900: #e65100,
A100: #ffd180,
A200: #ffab40,
A400: #ff9100,
A700: #ff6d00,
);
$md-deep-orange: (
50: #fbe9e7,
100: #ffccbc,
200: #ffab91,
300: #ff8a65,
400: #ff7043,
500: #ff5722,
600: #f4511e,
700: #e64a19,
800: #d84315,
900: #bf360c,
A100: #ff9e80,
A200: #ff6e40,
A400: #ff3d00,
A700: #dd2c00,
);
$md-brown: (
50: #efebe9,
100: #d7ccc8,
200: #bcaaa4,
300: #a1887f,
400: #8d6e63,
500: #795548,
600: #6d4c41,
700: #5d4037,
800: #4e342e,
900: #3e2723,
A100: #d7ccc8,
A200: #bcaaa4,
A400: #8d6e63,
A700: #5d4037,
);
$md-grey: (
0: #ffffff,
50: #fafafa,
100: #f5f5f5,
200: #eeeeee,
300: #e0e0e0,
400: #bdbdbd,
500: #9e9e9e,
600: #757575,
700: #616161,
800: #424242,
900: #212121,
1000: #000000,
A100: #ffffff,
A200: #eeeeee,
A400: #bdbdbd,
A700: #616161,
);
$md-blue-grey: (
50: #eceff1,
100: #cfd8dc,
200: #b0bec5,
300: #90a4ae,
400: #78909c,
500: #607d8b,
600: #546e7a,
700: #455a64,
800: #37474f,
900: #263238,
A100: #cfd8dc,
A200: #b0bec5,
A400: #78909c,
A700: #455a64,
);
$md-light-theme-foreground: (
divider: rgba(black, 0.12),
dividers: rgba(black, 0.12),
disabled: rgba(black, 0.26),
disabled-text: rgba(black, 0.26),
hint-text: rgba(black, 0.26),
secondary-text: rgba(black, 0.54),
icon: rgba(black, 0.54),
icons: rgba(black, 0.54),
text: rgba(black, 0.87)
);
$md-dark-theme-foreground: (
divider: rgba(white, 0.12),
dividers: rgba(white, 0.12),
disabled: rgba(white, 0.30),
disabled-text: rgba(white, 0.30),
hint-text: rgba(white, 0.30),
secondary-text: rgba(white, 0.70),
icon: white,
icons: white,
text: white
);
// Contrast colors. These are hard-coded because it is too difficult to calculate them.
// These contrast colors are pulled from the public Material Design spec swatches. While the
// contrast colors in the spec are not perscriptive, we will use them for convenience.
$black-87-opacity: rgba(black, 0.870588);
$white-87-opacity: rgba(white, 0.870588);
$md-contrast-palettes: (
$md-red: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: $black-87-opacity,
400: $black-87-opacity,
500: white,
600: white,
700: white,
800: $white-87-opacity,
900: $white-87-opacity,
A100: $black-87-opacity,
A200: white,
A400: white,
A700: white,
),
$md-pink: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: $black-87-opacity,
400: $black-87-opacity,
500: white,
600: white,
700: $white-87-opacity,
800: $white-87-opacity,
900: $white-87-opacity,
A100: $black-87-opacity,
A200: white,
A400: white,
A700: white,
),
$md-purple: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: white,
400: white,
500: $white-87-opacity,
600: $white-87-opacity,
700: $white-87-opacity,
800: $white-87-opacity,
900: $white-87-opacity,
A100: $black-87-opacity,
A200: white,
A400: white,
A700: white,
),
$md-deep-purple: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: white,
400: white,
500: $white-87-opacity,
600: $white-87-opacity,
700: $white-87-opacity,
800: $white-87-opacity,
900: $white-87-opacity,
A100: $black-87-opacity,
A200: white,
A400: $white-87-opacity,
A700: $white-87-opacity,
),
$md-indigo: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: white,
400: white,
500: $white-87-opacity,
600: $white-87-opacity,
700: $white-87-opacity,
800: $white-87-opacity,
900: $white-87-opacity,
A100: $black-87-opacity,
A200: white,
A400: white,
A700: $white-87-opacity,
),
$md-blue: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: $black-87-opacity,
400: $black-87-opacity,
500: white,
600: white,
700: white,
800: $white-87-opacity,
900: $white-87-opacity,
A100: $black-87-opacity,
A200: white,
A400: white,
A700: white,
),
$md-light-blue: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: $black-87-opacity,
400: $black-87-opacity,
500: white,
600: white,
700: white,
800: white,
900: $white-87-opacity,
A100: $black-87-opacity,
A200: $black-87-opacity,
A400: $black-87-opacity,
A700: white,
),
$md-cyan: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: $black-87-opacity,
400: $black-87-opacity,
500: white,
600: white,
700: white,
800: white,
900: $white-87-opacity,
A100: $black-87-opacity,
A200: $black-87-opacity,
A400: $black-87-opacity,
A700: $black-87-opacity,
),
$md-teal: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: $black-87-opacity,
400: $black-87-opacity,
500: white,
600: white,
700: white,
800: $white-87-opacity,
900: $white-87-opacity,
A100: $black-87-opacity,
A200: $black-87-opacity,
A400: $black-87-opacity,
A700: $black-87-opacity,
),
$md-green: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: $black-87-opacity,
400: $black-87-opacity,
500: white,
600: white,
700: white,
800: $white-87-opacity,
900: $white-87-opacity,
A100: $black-87-opacity,
A200: $black-87-opacity,
A400: $black-87-opacity,
A700: $black-87-opacity,
),
$md-light-green: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: $black-87-opacity,
400: $black-87-opacity,
500: $black-87-opacity,
600: $black-87-opacity,
700: $black-87-opacity,
800: white,
900: white,
A100: $black-87-opacity,
A200: $black-87-opacity,
A400: $black-87-opacity,
A700: $black-87-opacity,
),
$md-lime: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: $black-87-opacity,
400: $black-87-opacity,
500: $black-87-opacity,
600: $black-87-opacity,
700: $black-87-opacity,
800: $black-87-opacity,
900: white,
A100: $black-87-opacity,
A200: $black-87-opacity,
A400: $black-87-opacity,
A700: $black-87-opacity,
),
$md-yellow: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: $black-87-opacity,
400: $black-87-opacity,
500: $black-87-opacity,
600: $black-87-opacity,
700: $black-87-opacity,
800: $black-87-opacity,
900: $black-87-opacity,
A100: $black-87-opacity,
A200: $black-87-opacity,
A400: $black-87-opacity,
A700: $black-87-opacity,
),
$md-amber: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: $black-87-opacity,
400: $black-87-opacity,
500: $black-87-opacity,
600: $black-87-opacity,
700: $black-87-opacity,
800: $black-87-opacity,
900: $black-87-opacity,
A100: $black-87-opacity,
A200: $black-87-opacity,
A400: $black-87-opacity,
A700: $black-87-opacity,
),
$md-orange: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: $black-87-opacity,
400: $black-87-opacity,
500: $black-87-opacity,
600: $black-87-opacity,
700: $black-87-opacity,
800: white,
900: white,
A100: $black-87-opacity,
A200: $black-87-opacity,
A400: $black-87-opacity,
A700: black,
),
$md-deep-orange: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: $black-87-opacity,
400: $black-87-opacity,
500: white,
600: white,
700: white,
800: white,
900: white,
A100: $black-87-opacity,
A200: $black-87-opacity,
A400: white,
A700: white,
),
$md-brown: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: white,
400: white,
500: $white-87-opacity,
600: $white-87-opacity,
700: $white-87-opacity,
800: $white-87-opacity,
900: $white-87-opacity,
A100: $black-87-opacity,
A200: $black-87-opacity,
A400: white,
A700: $white-87-opacity,
),
$md-grey: (
0: $black-87-opacity,
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: $black-87-opacity,
400: $black-87-opacity,
500: $black-87-opacity,
600: $white-87-opacity,
700: $white-87-opacity,
800: $white-87-opacity,
900: $white-87-opacity,
1000: $white-87-opacity,
A100: $black-87-opacity,
A200: $black-87-opacity,
A400: $black-87-opacity,
A700: $white-87-opacity,
),
$md-blue-grey: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: $black-87-opacity,
400: white,
500: white,
600: $white-87-opacity,
700: $white-87-opacity,
800: $white-87-opacity,
900: $white-87-opacity,
A100: $black-87-opacity,
A200: $black-87-opacity,
A400: white,
A700: $white-87-opacity,
),
);

View File

@ -1,5 +0,0 @@
// Elements can have an "elevation" from 1 to 5, signified by shadows.
// See http://google.com/design/spec/what-is-material/objects-in-3d-space.html
$md-shadow-bottom-z-1: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
$md-shadow-bottom-z-2: 0 4px 8px 0 rgba(0, 0, 0, 0.4);

View File

@ -1,62 +0,0 @@
// ** Two main functions for users **
// md-palette: used for defining your theme in terms of Material hues.
// md-color: apply colors to components from the palette. Consumes the output of md-palette
// Implement the rem unit with SCSS so we don't have to actually set a font-size on
// the user's body element.
@function rem($multiplier) {
$font-size: 10px;
@return $multiplier * $font-size;
}
// For a given hue in a palette, return the contrast color from the map of contrast palettes.
@function md-contrast($color-map, $hue, $contrast-color-map) {
@return map-get(map-get($contrast-color-map, $color-map), $hue);
}
// Creates a map of hues to colors for a theme.
// $color-map
// $primary
// $lighter
// $darker
@function md-palette($color-map, $primary, $lighter, $darker, $contrast-color-map) {
$result: map_merge($color-map, (
default: map-get($color-map, $primary),
lighter: map-get($color-map, $lighter),
darker: map-get($color-map, $darker),
default-contrast: md-contrast($color-map, $primary, $contrast-color-map),
lighter-contrast: md-contrast($color-map, $lighter, $contrast-color-map),
darker-contrast: md-contrast($color-map, $darker, $contrast-color-map)
));
// For each hue in the palette, add a "-contrast" color to the map.
@each $hue, $color in $color-map {
$result: map_merge($result, (
"#{$hue}-contrast": md-contrast($color-map, $hue, $contrast-color-map)
))
}
@return $result;
}
// Gets a color for a material design component.
// $color-map: a map of {key: color}.
// $hue-key: key used to lookup the color in $colorMap. Defaults to 'default'
// If $hue-key is a number between 0 and 1, it will be treated as $opacity.
// $opacity: the opacity to apply to the color.
@function md-color($color-map, $hue-key: default, $opacity: 1) {
// If hueKey is a number between zero and one, then it actually contains an
// opacity value, so recall this function with the default hue and that given opacity.
@if type-of($hue-key) == number and $hue-key >= 0 and $hue-key <= 1 {
@return md-color($color-map, default, $hue-key)
}
$color: map-get($color-map, $hue-key);
$opacity: if(opacity($color) < 1, opacity($color), $opacity);
@return rgba($color, $opacity);
}

View File

@ -1,61 +0,0 @@
@import 'theme-functions';
// Font
$font-family: RobotoDraft, Roboto, 'Helvetica Neue', sans-serif !default;
// Layout
$baseline-grid: 8px !default;
$layout-breakpoint-sm: 600px !default;
$layout-breakpoint-md: 960px !default;
$layout-breakpoint-lg: 1200px !default;
$layout-gutter-width: ($baseline-grid * 2) !default;
// Typography
$md-body-font-size-base: rem(1.400) !default;
// App bar variables
$app-bar-height: 64px;
// Toast
$toast-height: $baseline-grid * 3 !default;
$toast-margin: $baseline-grid * 1 !default;
// Whiteframes
$whiteframe-shadow-z1: 0px 2px 5px 0 rgba(0,0,0,0.26) !default;
$whiteframe-zindex-z1: 1 !default;
$whiteframe-shadow-z2: 0px 8px 17px rgba(0,0,0,0.2) !default;
$whiteframe-zindex-z2: 2 !default;
$whiteframe-shadow-z3: 0px 17px 50px rgba(0,0,0,0.19) !default;
$whiteframe-zindex-z3: 3 !default;
$whiteframe-shadow-z4: 0px 16px 28px 0 rgba(0,0,0,0.22) !default;
$whiteframe-zindex-z4: 4 !default;
$whiteframe-shadow-z5: 0px 27px 24px 0 rgba(0,0,0,0.2) !default;
$whiteframe-zindex-z5: 5 !default;
// Z-indexes
$z-index-tooltip: 100 !default;
$z-index-dialog: 80 !default;
$z-index-toast: 90 !default;
$z-index-bottom-sheet: 70 !default;
$z-index-sidenav: 60 !default;
$z-index-backdrop: 50 !default;
$z-index-fab: 20 !default;
// Easing Curves
$swift-ease-out-duration: 0.4s !default;
$swift-ease-out-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default;
$swift-ease-out: all $swift-ease-out-duration $swift-ease-out-timing-function !default;
$swift-ease-in-duration: 0.3s !default;
$swift-ease-in-timing-function: cubic-bezier(0.55, 0, 0.55, 0.2) !default;
$swift-ease-in: all $swift-ease-in-duration $swift-ease-in-timing-function !default;
$swift-ease-in-out-duration: 0.5s !default;
$swift-ease-in-out-timing-function: cubic-bezier(0.35, 0, 0.25, 1) !default;
$swift-ease-in-out: all $swift-ease-in-out-duration $swift-ease-in-out-timing-function !default;

View File

@ -1,130 +0,0 @@
import {
AsyncTestCompleter,
TestComponentBuilder,
beforeEach,
beforeEachProviders,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
xit,
} from 'angular2/testing_internal';
import {Component, ViewMetadata, bind, provide, DebugElement} from 'angular2/core';
import {UrlResolver} from 'angular2/compiler';
import {MdButton, MdAnchor} from 'angular2_material/src/components/button/button';
import {TestUrlResolver} from './test_url_resolver';
export function main() {
describe('MdButton', () => {
let builder: TestComponentBuilder;
beforeEachProviders(() => [
// Need a custom URL resolver for ng-material template files in order for them to work
// with both JS and Dart output.
provide(UrlResolver, {useValue: new TestUrlResolver()})
]);
beforeEach(inject([TestComponentBuilder], (tcb) => { builder = tcb; }));
describe('button[mdButton]', () => {
it('should handle a click on the button', inject([AsyncTestCompleter], (async) => {
builder.createAsync(TestApp).then(fixture => {
let testComponent = fixture.debugElement.componentInstance;
let buttonDebugElement = getChildDebugElement(fixture.debugElement, 'button');
buttonDebugElement.nativeElement.click();
expect(testComponent.clickCount).toBe(1);
async.done();
});
}), 10000);
it('should disable the button', inject([AsyncTestCompleter], (async) => {
builder.createAsync(TestApp).then(fixture => {
let testAppComponent = fixture.debugElement.componentInstance;
let buttonDebugElement = getChildDebugElement(fixture.debugElement, 'button');
let buttonElement = buttonDebugElement.nativeElement;
// The button should initially be enabled.
expect(buttonElement.disabled).toBe(false);
// After the disabled binding has been changed.
testAppComponent.isDisabled = true;
fixture.detectChanges();
// The button should should now be disabled.
expect(buttonElement.disabled).toBe(true);
// Clicking the button should not invoke the handler.
buttonElement.click();
expect(testAppComponent.clickCount).toBe(0);
async.done();
});
}), 10000);
});
describe('a[mdButton]', () => {
const anchorTemplate = `<a mdButton href="http://google.com" [disabled]="isDisabled">Go</a>`;
beforeEach(() => {
builder = builder.overrideView(
TestApp, new ViewMetadata({template: anchorTemplate, directives: [MdAnchor]}));
});
it('should remove disabled anchors from tab order', inject([AsyncTestCompleter], (async) => {
builder.createAsync(TestApp).then(fixture => {
let testAppComponent = fixture.debugElement.componentInstance;
let anchorDebugElement = getChildDebugElement(fixture.debugElement, 'a');
let anchorElement = anchorDebugElement.nativeElement;
// The anchor should initially be in the tab order.
expect(anchorElement.tabIndex).toBe(0);
// After the disabled binding has been changed.
testAppComponent.isDisabled = true;
fixture.detectChanges();
// The anchor should now be out of the tab order.
expect(anchorElement.tabIndex).toBe(-1);
async.done();
});
it('should preventDefault for disabled anchor clicks',
inject([AsyncTestCompleter], (async) => {
// No clear way to test this; see https://github.com/angular/angular/issues/3782
async.done();
}));
}), 10000);
});
});
}
/** Gets a child DebugElement by tag name. */
function getChildDebugElement(parent: DebugElement, tagName: string): DebugElement {
var el = parent.query(debugEl => debugEl.nativeNode.tagName.toLowerCase() == tagName);
return <DebugElement>el;
}
/** Test component that contains an MdButton. */
@Component({
selector: 'test-app',
directives: [MdButton],
template:
`<button mdButton type="button" (click)="increment()" [disabled]="isDisabled">Go</button>`
})
class TestApp {
clickCount: number = 0;
isDisabled: boolean = false;
increment() {
this.clickCount++;
}
}

View File

@ -1,21 +0,0 @@
library ng_material.test_url_resolver;
import 'package:angular2/src/platform/browser/browser_adapter.dart';
import 'package:angular2/src/compiler/url_resolver.dart';
void commonDemoSetup() {
BrowserDomAdapter.makeCurrent();
}
class TestUrlResolver extends UrlResolver {
@override
String resolve(String baseUrl, String url) {
const MATERIAL_PKG = 'package:angular2_material/';
if (url.startsWith(MATERIAL_PKG)) {
return '/packages/angular2_material/' +
url.substring(MATERIAL_PKG.length);
}
return super.resolve(baseUrl, url);
}
}

View File

@ -1,16 +0,0 @@
import {UrlResolver} from 'angular2/src/compiler/url_resolver';
export class TestUrlResolver extends UrlResolver {
constructor() {
super();
}
resolve(baseUrl: string, url: string): string {
// The standard UrlResolver looks for "package:" templateUrls in
// node_modules, however in our repo we host material widgets at the root.
if (url.startsWith('package:angular2_material/')) {
return '/base/dist/js/dev/es5/' + url.substring(8);
}
return super.resolve(baseUrl, url);
}
}

View File

@ -1,3 +0,0 @@
library playground.e2e_test.material.button_spec;
main() {}

View File

@ -1,10 +0,0 @@
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
describe('mdButton', function() {
var url = 'playground/src/material/button/index.html';
beforeEach(() => { browser.get(url); });
afterEach(verifyNoBrowserErrors);
// Buttons are broken right now, see https://github.com/angular/angular/issues/1602
});

View File

@ -1,3 +0,0 @@
library playground.e2e_test.material.checkbox_spec;
main() {}

View File

@ -1,18 +0,0 @@
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
describe('md-checkbox', function() {
var url = 'playground/src/material/checkbox/index.html';
beforeEach(() => { browser.get(url); });
afterEach(verifyNoBrowserErrors);
it('should toggle a checkbox', function() {
var checkbox = element.all(by.css('md-checkbox')).first();
checkbox.click();
expect(checkbox.getAttribute('aria-checked')).toEqual('true');
checkbox.click();
expect(checkbox.getAttribute('aria-checked')).toEqual('false');
});
});

View File

@ -1,3 +0,0 @@
library playground.e2e_test.material.dialog_spec;
main() {}

View File

@ -1,21 +0,0 @@
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
describe('md-dialog', function() {
var url = 'playground/src/material/dialog/index.html';
beforeEach(() => { browser.get(url); });
afterEach(verifyNoBrowserErrors);
xit('should open a dialog', function() {
var openButton = element(by.id('open'));
openButton.click();
var dialog = element(by.css('.md-dialog'));
expect(dialog.isPresent()).toEqual(true);
dialog.sendKeys(protractor.Key.ESCAPE);
expect(element(by.css('.md-dialog')).isPresent()).toEqual(false);
});
});

View File

@ -1,3 +0,0 @@
library playground.e2e_test.material.grid_list_spec;
main() {}

View File

@ -1,17 +0,0 @@
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
// TODO: Enable tests once #5132 is fixed.
xdescribe('md-grid-list', function() {
var url = 'playground/src/material/grid_list/index.html';
beforeEach(() => { browser.get(url); });
afterEach(verifyNoBrowserErrors);
it('should set tiles into different positions', () => {
var tiles = element.all(by.css('md-grid-list#complex md-grid-tile'));
// If the grid-list was not doing any layout, all of the tiles would have the same position.
// So our smoke test simply checks that any two tiles are in different positions.
expect(tiles.first().getLocation()).not.toEqual(tiles.last().getLocation());
});
});

View File

@ -1,3 +0,0 @@
library playground.e2e_test.material.input_spec;
main() {}

View File

@ -1,16 +0,0 @@
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
describe('md-input', function() {
var url = 'playground/src/material/input/index.html';
beforeEach(() => { browser.get(url); });
afterEach(verifyNoBrowserErrors);
it('should enter a value to the input', () => {
var input = element.all(by.css('md-input-container input')).first();
input.sendKeys('Hello');
expect(input.getAttribute('value')).toEqual('Hello');
});
});

View File

@ -1,3 +0,0 @@
library playground.e2e_test.material.progress_linear_spec;
main() {}

View File

@ -1,24 +0,0 @@
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
describe('md-progress-linear', function() {
var url = 'playground/src/material/progress-linear/index.html';
beforeEach(() => { browser.get(url); });
afterEach(verifyNoBrowserErrors);
it('should increment and decrement progress', function() {
var progressBar = element.all(by.css('md-progress-linear')).first();
var incrementButton = element(by.id('increment'));
var decrementButton = element(by.id('decrement'));
// Really a Promise<string> but can be coerced to a number after resolving
var initialValue: any = progressBar.getAttribute('aria-valuenow');
incrementButton.click();
expect(progressBar.getAttribute('aria-valuenow')).toBeGreaterThan(initialValue);
decrementButton.click();
decrementButton.click();
expect(progressBar.getAttribute('aria-valuenow')).toBeLessThan(initialValue);
});
});

View File

@ -1,3 +0,0 @@
library playground.e2e_test.material.radio_spec;
main() {}

View File

@ -1,21 +0,0 @@
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
describe('md-radio-button', function() {
var url = 'playground/src/material/radio/index.html';
beforeEach(() => { browser.get(url); });
afterEach(verifyNoBrowserErrors);
it('should check one radio button and then check another', () => {
var standaloneRadios = element.all(by.css('[name="element"]'));
var firstRadio = standaloneRadios.first();
var lastRadio = standaloneRadios.last();
firstRadio.click();
expect(firstRadio.getAttribute('aria-checked')).toEqual('true');
lastRadio.click();
expect(firstRadio.getAttribute('aria-checked')).toEqual('false');
expect(lastRadio.getAttribute('aria-checked')).toEqual('true');
});
});

View File

@ -4,7 +4,6 @@ environment:
dependencies:
observe: '^0.13.1'
angular2: '^<%= packageJson.version %>'
angular2_material: '^<%= packageJson.version %>'
browser: '^0.10.0'
dev_dependencies:
guinness2: '0.0.5'
@ -13,8 +12,6 @@ dev_dependencies:
dependency_overrides:
angular2:
path: ../angular2
angular2_material:
path: ../angular2_material
matcher: '0.12.0+1'
transformers:
- angular2/transform/codegen:
@ -27,14 +24,6 @@ transformers:
- web/src/hash_routing/index.dart
- web/src/hello_world/index.dart
- web/src/key_events/index.dart
- web/src/material/button/index.dart
- web/src/material/checkbox/index.dart
- web/src/material/dialog/index.dart
- web/src/material/grid_list/index.dart
- web/src/material/input/index.dart
- web/src/material/progress-linear/index.dart
- web/src/material/radio/index.dart
- web/src/material/switcher/index.dart
- web/src/model_driven_forms/index.dart
- web/src/observable_models/index.dart
- web/src/order_management/index.dart

View File

@ -1,12 +0,0 @@
Language: JavaScript
BasedOnStyle: Google
ColumnLimit: 100
TabWidth: 2
ContinuationIndentWidth: 4
MaxEmptyLinesToKeep : 2
AllowShortBlocksOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty

View File

@ -1,88 +0,0 @@
<style>
section {
background: #f7f7f7;
border-radius: 3px;
text-align: center;
margin: 1em;
position: relative !important;
padding-bottom: 10px;
}
.label {
position: absolute;
bottom: 5px;
left: 7px;
color: #ccc;
font-size: 14px;
}
.custom {
background-color: #ae0001;
color: #eeba30;
}
.custom:hover, .custom.md-button-focus {
background-color: #740001;
color: #d3a625;
}
</style>
<h1>Button demo</h1>
<p>
You just clicked: <span>{{previousClick}}</span>
</p>
<section>
<form (submit)="submit('form submit', $event)">
<button mdButton>SUBMIT</button>
<button>Native button</button>
</form>
<span class="label">form submit</span>
</section>
<section>
<span class="label">Regular button</span>
<button mdButton (click)="click('button')">BUTTON</button>
<button mdButton class="md-primary" (click)="click('primary')">PRIMARY</button>
<button mdButton disabled="disabled" (click)="click('disabled')">DISABLED</button>
<button mdButton class="md-accent" (click)="click('accent')">ACCENT</button>
<button mdButton class="md-warn" (click)="click('warn')">WARN</button>
<button mdButton class="custom" (click)="click('custom')">CUSTOM</button>
</section>
<section>
<span class="label">Raised button</span>
<button mdRaisedButton (click)="click('raised')">BUTTON</button>
<button mdRaisedButton class="md-primary" (click)="click('raised primary')">PRIMARY</button>
<button mdRaisedButton disabled="disabled" (click)="click('raised disabled')">DISABLED</button>
<button mdRaisedButton class="md-accent" (click)="click('raised accent')">ACCENT</button>
<button mdRaisedButton class="md-warn" (click)="click('raised warn')">WARN</button>
<button mdRaisedButton class="custom" (click)="click('custom raised')">CUSTOM</button>
</section>
<section>
<span class="label">Fab button</span>
<button mdFab (click)="click('fab')">BTN</button>
<button mdFab class="md-primary" (click)="click('fab primary')">PRMY</button>
<button mdFab disabled="disabled" (click)="click('fab disabled')">DIS</button>
<button mdFab class="md-accent" (click)="click('fab accent')">ACC</button>
<button mdFab class="md-warn" (click)="click('fab warn')">WRN</button>
<button mdFab class="custom" (click)="click('custom fab')">CSTM</button>
</section>
<section>
<span class="label">Anchor / hyperlink</span>
<a mdButton href="http://google.com" target="_blank">HREF</a>
<a mdButton href="http://google.com" disabled>DISABLED HREF</a>
<a mdRaisedButton target="_blank" href="http://google.com">RAISED HREF</a>
</section>
<section dir="rtl">
<span class="label" dir="ltr">Right-to-left</span>
<button mdButton (click)="click('Hebrew button')">לחצן</button>
<button mdRaisedButton (click)="click('Hebrew raised button')">העלה</button>
<a mdButton href="http://translate.google.com">עוגן</a>
</section>

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>ng-material button demo</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:400,500,700,400italic">
<style> * { font-family: RobotoDraft, Roboto, 'Helvetica Neue', sans-serif; } </style>
</head>
<body>
<demo-app>Loading...</demo-app>
$SCRIPTS$
</body>
</html>

View File

@ -1,44 +0,0 @@
import {bootstrap} from 'angular2/bootstrap';
import {bind, provide, Component, ViewEncapsulation} from 'angular2/core';
import {NgFor} from 'angular2/common';
import {UrlResolver} from 'angular2/compiler';
import {MdButton, MdAnchor} from 'angular2_material/src/components/button/button';
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
@Component({
selector: 'demo-app',
templateUrl: './demo_app.html',
directives: [MdButton, MdAnchor, NgFor],
encapsulation: ViewEncapsulation.None
})
class DemoApp {
previousClick: string;
action: string;
clickCount: number;
items: number[];
constructor() {
this.previousClick = 'Nothing';
this.action = "ACTIVATE";
this.clickCount = 0;
this.items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
}
click(msg: string) {
this.previousClick = msg;
}
submit(msg: string, event) {
event.preventDefault();
this.previousClick = msg;
}
increment() {
this.clickCount++;
}
}
export function main() {
commonDemoSetup();
bootstrap(DemoApp, [provide(UrlResolver, {useValue: new DemoUrlResolver()})]);
}

View File

@ -1,9 +0,0 @@
<div md-theme="default">
<h2>Checkbox demo</h2>
<md-checkbox (click)="increment()">Normal checkbox</md-checkbox>
<md-checkbox class="md-primary" (click)="increment()">Primary checkbox</md-checkbox>
<md-checkbox disabled (click)="increment()">Disabled checkbox</md-checkbox>
<p>Toggle count: {{toggleCount}}</p>
</div>

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>ng-material checkbox demo</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:400,500,700,400italic">
<style> * { font-family: RobotoDraft, Roboto; } </style>
</head>
<body>
<demo-app>Loading...</demo-app>
$SCRIPTS$
</body>
</html>

View File

@ -1,29 +0,0 @@
import {bootstrap} from 'angular2/bootstrap';
import {bind, provide, Component, Directive, ViewEncapsulation} from 'angular2/core';
import {UrlResolver} from 'angular2/compiler';
import {MdCheckbox} from 'angular2_material/src/components/checkbox/checkbox';
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
@Component({
selector: 'demo-app',
templateUrl: './demo_app.html',
directives: [MdCheckbox],
encapsulation: ViewEncapsulation.None
})
class DemoApp {
toggleCount: number;
constructor() {
this.toggleCount = 0;
}
increment() {
this.toggleCount++;
}
}
export function main() {
commonDemoSetup();
bootstrap(DemoApp, [provide(UrlResolver, {useValue: new DemoUrlResolver()})]);
}

View File

@ -1,23 +0,0 @@
library angular2_examples.material.demo_common;
import 'package:angular2/src/platform/browser/browser_adapter.dart';
import 'package:angular2/src/compiler/url_resolver.dart';
void commonDemoSetup() {
BrowserDomAdapter.makeCurrent();
}
class DemoUrlResolver extends UrlResolver {
@override
String resolve(String baseUrl, String url) {
const MATERIAL_PKG = 'package:angular2_material/';
// We run a proxy server in front of pub serve that prepends "example" to
// paths
if (url.startsWith(MATERIAL_PKG)) {
return '/examples/packages/angular2_material/' +
url.substring(MATERIAL_PKG.length);
}
return super.resolve(baseUrl, url);
}
}

View File

@ -1,27 +0,0 @@
import {print} from 'angular2/src/facade/lang';
import {UrlResolver} from 'angular2/src/compiler/url_resolver';
import {isPresent, isBlank, RegExpWrapper, StringWrapper} from 'angular2/src/facade/lang';
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
import {Injectable} from 'angular2/core';
import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter';
export function commonDemoSetup(): void {
BrowserDomAdapter.makeCurrent();
}
@Injectable()
export class DemoUrlResolver extends UrlResolver {
constructor() {
super();
}
resolve(baseUrl: string, url: string): string {
// The standard UrlResolver looks for "package:" templateUrls in
// node_modules, however in our repo we host material widgets at the root.
if (url.startsWith('package:angular2_material/')) {
return '/' + url.substring(8);
}
return super.resolve(baseUrl, url);
}
}

View File

@ -1,32 +0,0 @@
<div>
<h2>Dialog demo</h2>
<button id="open" type="button" (click)="open()" [disabled]="!!dialogRef">
Open a dialog
</button>
<button type="button" (click)="close()" [disabled]="!dialogRef">
Close the dialog
</button>
<p>
Last result: {{lastResult}}
</p>
<hr>
<p> Here are some paragaphs to make the page scrollable</p>
<p> Here are some paragaphs to make the page scrollable</p>
<p> Here are some paragaphs to make the page scrollable</p>
<p> Here are some paragaphs to make the page scrollable</p>
<p> Here are some paragaphs to make the page scrollable</p>
<p> Here are some paragaphs to make the page scrollable</p>
<p> Here are some paragaphs to make the page scrollable</p>
<p> Here are some paragaphs to make the page scrollable</p>
<p> Here are some paragaphs to make the page scrollable</p>
<p> Here are some paragaphs to make the page scrollable</p>
<p> Here are some paragaphs to make the page scrollable</p>
<p> Here are some paragaphs to make the page scrollable</p>
<p> Here are some paragaphs to make the page scrollable</p>
</div>

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>ng-material dialog demo</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:400,500,700,400italic">
<style> * { font-family: RobotoDraft, Roboto; } </style>
</head>
<body class="dialog-demo">
<demo-app>Loading...</demo-app>
$SCRIPTS$
</body>
</html>

View File

@ -1,94 +0,0 @@
import {bootstrap} from 'angular2/bootstrap';
import {bind, provide, ElementRef, ComponentRef, Component, ViewEncapsulation} from 'angular2/core';
import {UrlResolver} from 'angular2/compiler';
import {
MdDialog,
MdDialogRef,
MdDialogConfig
} from 'angular2_material/src/components/dialog/dialog';
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
import {isPresent} from 'angular2/src/facade/lang';
@Component({
selector: 'demo-app',
viewProviders: [MdDialog],
templateUrl: './demo_app.html',
directives: [],
encapsulation: ViewEncapsulation.None,
})
class DemoApp {
dialog: MdDialog;
elementRef: ElementRef;
dialogRef: MdDialogRef;
dialogConfig: MdDialogConfig;
lastResult: string;
constructor(mdDialog: MdDialog, elementRef: ElementRef) {
this.dialog = mdDialog;
this.elementRef = elementRef;
this.dialogConfig = new MdDialogConfig();
this.dialogConfig.width = '60%';
this.dialogConfig.height = '60%';
this.lastResult = '';
}
open() {
if (isPresent(this.dialogRef)) {
return;
}
this.dialog.open(SimpleDialogComponent, this.elementRef, this.dialogConfig)
.then(ref => {
this.dialogRef = ref;
ref.instance.numCoconuts = 777;
ref.whenClosed.then(result => {
this.dialogRef = null;
this.lastResult = result;
});
});
}
close() {
this.dialogRef.close();
}
}
@Component({
selector: 'simple-dialog',
inputs: ['numCoconuts'],
encapsulation: ViewEncapsulation.None,
template: `
<h2>This is the dialog content</h2>
<p>There are {{numCoconuts}} coconuts.</p>
<p>Return: <input (input)="updateValue($event)"></p>
<button type="button" (click)="done()">Done</button>
`
})
class SimpleDialogComponent {
numCoconuts: number;
dialogRef: MdDialogRef;
toReturn: string;
constructor(dialogRef: MdDialogRef) {
this.numCoconuts = 0;
this.dialogRef = dialogRef;
this.toReturn = '';
}
updateValue(event) {
this.toReturn = event.target.value;
}
done() {
this.dialogRef.close(this.toReturn);
}
}
export function main() {
commonDemoSetup();
bootstrap(DemoApp, [provide(UrlResolver, {useValue: new DemoUrlResolver()})]);
}

View File

@ -1,41 +0,0 @@
<style>
md-grid-tile {
background-color: lightblue;
}
md-grid-list {
min-height: 400px;
}
</style>
<div>
<h2>grid-list demo</h2>
<md-grid-list cols="4" row-height="50px" gutter-size="2em" id="complex">
<md-grid-tile rowspan="1" colspan="2"> Tile #1 </md-grid-tile>
<md-grid-tile rowspan="1" colspan="1"> Tile #2 </md-grid-tile>
<md-grid-tile rowspan="3" colspan="1"> Tile #3 </md-grid-tile>
<md-grid-tile rowspan="2" colspan="2"> Tile #4 </md-grid-tile>
<md-grid-tile rowspan="1" colspan="3"> Tile #5 </md-grid-tile>
</md-grid-list>
<hr>
<md-grid-list cols="4" row-height="50px" gutter-size="2em" id="simple">
<md-grid-tile rowspan="1" colspan="1"> Tile #1 </md-grid-tile>
<md-grid-tile rowspan="1" colspan="1"> Tile #2 </md-grid-tile>
<md-grid-tile rowspan="1" colspan="1"> Tile #3 </md-grid-tile>
<md-grid-tile rowspan="1" colspan="1"> Tile #4 </md-grid-tile>
<md-grid-tile rowspan="1" colspan="1"> Tile #5 </md-grid-tile>
<md-grid-tile rowspan="1" colspan="1"> Tile #6 </md-grid-tile>
<md-grid-tile rowspan="1" colspan="1"> Tile #7 </md-grid-tile>
</md-grid-list>
</div>

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>ng-material grid-list demo</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:400,500,700,400italic">
<style> * { font-family: RobotoDraft, Roboto; } </style>
</head>
<body>
<demo-app>Loading...</demo-app>
$SCRIPTS$
</body>
</html>

View File

@ -1,27 +0,0 @@
import {bootstrap} from 'angular2/bootstrap';
import {bind, provide, Component, ViewEncapsulation} from 'angular2/core';
import {MdGridList, MdGridTile} from 'angular2_material/src/components/grid_list/grid_list';
import {UrlResolver} from 'angular2/compiler';
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
@Component({
selector: 'demo-app',
templateUrl: './demo_app.html',
directives: [MdGridList, MdGridTile],
encapsulation: ViewEncapsulation.None,
})
class DemoApp {
tile3RowSpan: number;
tile3ColSpan: number;
constructor() {
this.tile3RowSpan = 3;
this.tile3ColSpan = 3;
}
}
export function main() {
commonDemoSetup();
bootstrap(DemoApp, [provide(UrlResolver, {useValue: new DemoUrlResolver()})]);
}

View File

@ -1,43 +0,0 @@
<style>@import "package:angular2_material/src/components/input/input.css";</style>
<style>
body {
max-width: 500px;
}
</style>
<div>
<h2>input demo</h2>
<h3>Normal input</h3>
<md-input-container>
<label>Name</label>
<input md-input>
</md-input-container>
<h3>Pre-filled value</h3>
<md-input-container>
<label>Favorite Framework</label>
<input value="Angular">
</md-input-container>
<h3>Disabled input</h3>
<md-input-container>
<label>ID Number</label>
<input disabled>
</md-input-container>
<h3>Disabled, pre-filled input</h3>
<md-input-container>
<label>Best TV show</label>
<input disabled value="Firefly">
</md-input-container>
<!--<h3>textarea</h3>
<md-input-container>
<label>What I did on my summer vaccation</label>
<textarea></textarea>
</md-input-container>-->
</div>

View File

@ -1,14 +0,0 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>ng-material input demo</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:400,500,700,400italic">
<style> * { font-family: RobotoDraft, Roboto; }
</style>
</head>
<body>
<demo-app>Loading...</demo-app>
$SCRIPTS$
</body>
</html>

View File

@ -1,20 +0,0 @@
import {bootstrap} from 'angular2/bootstrap';
import {bind, provide, Component, ViewEncapsulation} from 'angular2/core';
import {MdInputContainer, MdInput} from 'angular2_material/src/components/input/input';
import {UrlResolver} from 'angular2/compiler';
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
@Component({
selector: 'demo-app',
templateUrl: './demo_app.html',
directives: [MdInputContainer, MdInput],
encapsulation: ViewEncapsulation.None
})
class DemoApp {
constructor() {}
}
export function main() {
commonDemoSetup();
bootstrap(DemoApp, [provide(UrlResolver, {useValue: new DemoUrlResolver()})]);
}

View File

@ -1,40 +0,0 @@
<div style="width: 500px;">
<h2>Progress-linear demo</h2>
<p>
Determinate: primary
<md-progress-linear mode="determinate" [value]="progress" class="md-accent">
</md-progress-linear>
</p>
<p>
Determinate: accent
<md-progress-linear mode="determinate" [value]="progress" class="md-primary">
</md-progress-linear>
</p>
<p>
Buffer
<md-progress-linear mode="buffer"
[value]="progress" [buffer-value]="progress + (200 / progress)" class="md-warn">
</md-progress-linear>
</p>
<p>
Indeterminate
<md-progress-linear mode="indeterminate" class="md-primary">
</md-progress-linear>
</p>
<p>
Query
<md-progress-linear mode="query" class="md-accent">
</md-progress-linear>
</p>
<!--<md-progress-linear></md-progress-linear>-->
<p>Progress: {{progress}}</p>
<button type="button" (click)="step(10)" id="increment">Increment</button>
<button type="button" (click)="step(-10)" id="decrement">Decrement</button>
</div>

View File

@ -1,15 +0,0 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>ng-material progress-linear demo</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:400,500,700,400italic">
<style> * { font-family: RobotoDraft, Roboto; } </style>
</head>
<body>
<demo-app>Loading...</demo-app>
$SCRIPTS$
</body>
</html>

View File

@ -1,28 +0,0 @@
import {bootstrap} from 'angular2/bootstrap';
import {bind, provide, Component, ViewEncapsulation} from 'angular2/core';
import {MdProgressLinear} from 'angular2_material/src/components/progress-linear/progress_linear';
import {UrlResolver} from 'angular2/src/compiler/url_resolver';
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
@Component({
selector: 'demo-app',
templateUrl: './demo_app.html',
directives: [MdProgressLinear],
encapsulation: ViewEncapsulation.None,
})
class DemoApp {
progress: number;
constructor() {
this.progress = 40;
}
step(s: number) {
this.progress += s;
}
}
export function main() {
commonDemoSetup();
bootstrap(DemoApp, [provide(UrlResolver, {useValue: new DemoUrlResolver()})]);
}

View File

@ -1,41 +0,0 @@
<style>
md-radio-button {
max-width: 200px;
}
</style>
<div>
<h2>Radio buttons</h2>
<h3>Inside of a radiogroup</h3>
<md-radio-group #scifi (change)="onGroupChange()" id="scifi-group">
<md-radio-button value="star-wars">Star Wars</md-radio-button>
<md-radio-button value="star-trek" id="special-radio">Star Trek</md-radio-button>
<md-radio-button value="bsg" disabled>Battlestar Galactica</md-radio-button>
<md-radio-button [value]="thirdValue">Dr. Who</md-radio-button>
</md-radio-group>
<p>Your selection: {{scifi.value}}</p>
<p>radio group value change count: {{groupValueChangeCount}}</p>
<hr>
<h3>Standalone</h3>
<md-radio-button name="element" (click)="onIndividualClick()">Earth</md-radio-button>
<md-radio-button name="element" (click)="onIndividualClick()">Fire</md-radio-button>
<md-radio-button name="element" (click)="onIndividualClick()" disabled>Wind (disabled)</md-radio-button>
<md-radio-button name="element" (click)="onIndividualClick()">Heart</md-radio-button>
<p>individual radio value change count: {{individualValueChanges}}</p>
<hr>
<h3>Disabled radio group</h3>
<p>Chosen: {{pokemon}}</p>
<md-radio-group disabled [value]="pokemon">
<md-radio-button value="fire">Charmander</md-radio-button>
<md-radio-button value="leaf">Bulbasaur</md-radio-button>
<md-radio-button value="water">Squirtle</md-radio-button>
</md-radio-group>
<button type="button" (click)="chooseCharmander()">Choose Charmander</button>
</div>

View File

@ -1,15 +0,0 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>ng-material radio demo</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:400,500,700,400italic">
<style> * { font-family: RobotoDraft, Roboto; } </style>
</head>
<body>
<demo-app>Loading...</demo-app>
$SCRIPTS$
</body>
</html>

View File

@ -1,46 +0,0 @@
import {bootstrap} from 'angular2/bootstrap';
import {bind, provide, Component, ViewEncapsulation} from 'angular2/core';
import {UrlResolver} from 'angular2/compiler';
import {MdRadioButton, MdRadioGroup} from 'angular2_material/src/components/radio/radio_button';
import {MdRadioDispatcher} from 'angular2_material/src/components/radio/radio_dispatcher';
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
@Component({
selector: 'demo-app',
viewProviders: [MdRadioDispatcher],
templateUrl: './demo_app.html',
directives: [MdRadioGroup, MdRadioButton],
encapsulation: ViewEncapsulation.None,
})
class DemoApp {
thirdValue;
groupValueChangeCount;
individualValueChanges;
pokemon;
someTabindex;
constructor() {
this.thirdValue = 'dr-who';
this.groupValueChangeCount = 0;
this.individualValueChanges = 0;
this.pokemon = '';
this.someTabindex = 888;
}
chooseCharmander() {
this.pokemon = 'fire';
}
onGroupChange() {
this.groupValueChangeCount++;
}
onIndividualClick() {
this.individualValueChanges++;
}
}
export function main() {
commonDemoSetup();
bootstrap(DemoApp, [provide(UrlResolver, {useValue: new DemoUrlResolver()})]);
}

View File

@ -1,9 +0,0 @@
<div md-theme="default">
<h2>NgSwitch demo</h2>
<md-switch (click)="increment()">Normal switch</md-switch>
<md-switch class="md-primary" (click)="increment()">Primary switch</md-switch>
<md-switch disabled (click)="increment()">Disabled switch</md-switch>
<p>Toggle count: {{toggleCount}}</p>
</div>

View File

@ -1,19 +0,0 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>ng-material switch demo</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:400,500,700,400italic">
<style>
* {
font-family: RobotoDraft, Roboto;
}
</style>
</head>
<body>
<demo-app>Loading...</demo-app>
$SCRIPTS$
</body>
</html>

View File

@ -1,28 +0,0 @@
import {bootstrap} from 'angular2/bootstrap';
import {bind, provide, Component, ViewEncapsulation} from 'angular2/core';
import {MdSwitch} from 'angular2_material/src/components/switcher/switch';
import {UrlResolver} from 'angular2/src/compiler/url_resolver';
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
@Component({
selector: 'demo-app',
templateUrl: './demo_app.html',
directives: [MdSwitch],
encapsulation: ViewEncapsulation.None,
})
class DemoApp {
toggleCount: number;
constructor() {
this.toggleCount = 0;
}
increment() {
this.toggleCount++;
}
}
export function main() {
commonDemoSetup();
bootstrap(DemoApp, [provide(UrlResolver, {useValue: new DemoUrlResolver()})]);
}

View File

@ -26,7 +26,6 @@ git clone https://github.com/dart-lang/dev_compiler.git tmp/dev_compiler
# Convert TypeScript to Dart
./node_modules/.bin/gulp build/packages.dart
./node_modules/.bin/gulp build.dart.material.css
./node_modules/.bin/gulp build/pubspec.dart
node ./scripts/ci/dart_ddc/pubspec_for_ddc.js \
--pubspec-file=dist/dart/playground/pubspec.yaml
@ -45,14 +44,6 @@ $DART_SDK/bin/dart $DDC_DIR/bin/dartdevc.dart \
src/hash_routing/index.dart \
src/hello_world/index.dart \
src/key_events/index.dart \
src/material/button/index.dart \
src/material/checkbox/index.dart \
src/material/dialog/index.dart \
src/material/grid_list/index.dart \
src/material/input/index.dart \
src/material/progress-linear/index.dart \
src/material/radio/index.dart \
src/material/switcher/index.dart \
src/model_driven_forms/index.dart \
src/observable_models/index.dart \
src/order_management/index.dart \

View File

@ -25,8 +25,6 @@ function killServer () {
# serverPid=$!
#fi
./node_modules/.bin/gulp build.css.material&
trap killServer EXIT
# wait for server to come up!

View File

@ -15,8 +15,6 @@ function killServer () {
./node_modules/.bin/gulp serve.js.prod&
serverPid=$!
./node_modules/.bin/gulp build.css.material&
trap killServer EXIT
# wait for server to come up!

View File

@ -17,7 +17,6 @@ gulp clean
gulp build/packages.dart
gulp build/pubspec.dart
gulp build/analyze.dart
gulp build.dart.material
PKG_DIR=$ROOT_DIR/dist/pub
rm -fr $PKG_DIR
@ -36,5 +35,4 @@ function publishModule {
publishModule angular2
publishModule benchpress
publishModule benchmarks
publishModule angular2_material
publishModule angular2_testing

View File

@ -13,7 +13,6 @@ System.config({
paths: {
'benchpress/*': 'dist/js/dev/es5/benchpress/*.js',
'angular2/*': 'dist/js/dev/es5/angular2/*.js',
'angular2_material/*': 'dist/js/dev/es5/angular2_material/*.js',
'rxjs/*': 'node_modules/rxjs/*.js'
}
});

View File

@ -66,7 +66,7 @@ let customParams = {
cd8: `${os.cpus().length} x ${os.cpus()[0].model}`,
// HW - Memory Info
cd9: `${Math.round(os.totalmem()/1024/1024/1024)}GB`,
// gulp --projects (angular2,angular2_material)
// gulp --projects (angular2)
cd13: minimist(process.argv.slice(2)).projects
};

View File

@ -3,7 +3,6 @@
<script>
var scriptUrls;
var loadRuntimePackages = [
'angular2_material',
'benchmarks',
'playground',
// TODO(rado): These helpers don't end up in the bundle, thus they should

View File

@ -4,7 +4,6 @@
<script>
var scriptUrls;
var loadRuntimePackages = [
'angular2_material',
'benchmarks',
'playground',
// TODO(rado): These helpers don't end up in the bundle, thus they should

View File

@ -57,14 +57,6 @@ const kServedPaths = [
'playground/src/upgrade',
'playground/src/zippy_component',
'playground/src/async',
'playground/src/material/button',
'playground/src/material/checkbox',
'playground/src/material/dialog',
'playground/src/material/grid_list',
'playground/src/material/input',
'playground/src/material/progress-linear',
'playground/src/material/radio',
'playground/src/material/switcher',
'playground/src/web_workers/kitchen_sink',
'playground/src/web_workers/todo',
'playground/src/web_workers/images',
@ -91,12 +83,6 @@ module.exports = function makeBrowserTree(options, destinationPath) {
});
}
if (modules.angular2_material) {
var angular2MaterialTree =
new Funnel('modules/angular2_material',
{include: ['**/**'], exclude: ['e2e_test/**'], destDir: '/angular2_material/'});
}
if (modules.benchmarks) {
var benchmarksTree =
new Funnel('modules/benchmarks',
@ -129,7 +115,6 @@ module.exports = function makeBrowserTree(options, destinationPath) {
var modulesTree = mergeTrees([
angular2Tree,
angular2MaterialTree,
benchmarksTree,
benchmarksExternalTree,
payloadTestsTree,
@ -226,8 +211,7 @@ module.exports = function makeBrowserTree(options, destinationPath) {
}
if (modules.angular2_material || modules.benchmarks || modules.benchmarks_external ||
modules.playground) {
if (modules.benchmarks || modules.benchmarks_external || modules.playground) {
var assetsTree = new Funnel(
modulesTree, {include: ['**/*'], exclude: ['**/*.{html,ts,dart}'], destDir: '/'});
}

View File

@ -11,8 +11,6 @@ module.exports = function(gulp, plugins, config) {
var supportedModules = [
'dist/dart/angular2',
// TODO: blocked by https://github.com/angular/angular/issues/3518
// 'dist/dart/angular2_material',
'dist/dart/benchpress'
];