feat(material): first ng2 material design components
This commit is contained in:
parent
ffe13078e5
commit
f149ae79c6
24
gulpfile.js
24
gulpfile.js
|
@ -1,6 +1,8 @@
|
|||
var autoprefixer = require('gulp-autoprefixer');
|
||||
var format = require('gulp-clang-format');
|
||||
var gulp = require('gulp');
|
||||
var gulpPlugins = require('gulp-load-plugins')();
|
||||
var sass = require('gulp-sass');
|
||||
var shell = require('gulp-shell');
|
||||
var runSequence = require('run-sequence');
|
||||
var madge = require('madge');
|
||||
|
@ -152,7 +154,7 @@ var CONFIG = {
|
|||
src: ['modules/**/*.css'],
|
||||
pipes: {}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
multicopy: {
|
||||
js: {
|
||||
|
@ -697,3 +699,23 @@ gulp.task('build.js', ['build.js.dev', 'build.js.prod', 'build.js.cjs', 'bundle.
|
|||
gulp.task('clean', ['build/clean.js', 'build/clean.dart', 'build/clean.docs']);
|
||||
|
||||
gulp.task('build', ['build.js', 'build.dart']);
|
||||
|
||||
|
||||
// ------------
|
||||
// angular material testing rules
|
||||
gulp.task('build/css.js.dev', function() {
|
||||
return gulp.src('modules/*/src/**/*.scss')
|
||||
.pipe(sass())
|
||||
.pipe(autoprefixer())
|
||||
.pipe(gulp.dest(CONFIG.dest.js.dev.es5));
|
||||
});
|
||||
|
||||
// TODO: this target is temporary until we find a way to use the SASS transformer
|
||||
gulp.task('build/css.dart', function() {
|
||||
return gulp.src('dist/dart/angular2_material/lib/src/**/*.scss')
|
||||
.pipe(sass())
|
||||
.pipe(autoprefixer())
|
||||
.pipe(gulp.dest('dist/dart/angular2_material/lib/src'));
|
||||
});
|
||||
|
||||
gulp.task('build.material', ['build.js.dev', 'build/css.js.dev']);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {Injector, bind, OpaqueToken} from 'angular2/di';
|
||||
import {Type, isBlank, isPresent, BaseException, assertionsEnabled, print, stringify} from 'angular2/src/facade/lang';
|
||||
import {Injector, bind, OpaqueToken, Optional} from 'angular2/di';
|
||||
import {NumberWrapper, Type, isBlank, isPresent, BaseException,
|
||||
assertionsEnabled, print, stringify} from 'angular2/src/facade/lang';
|
||||
import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter';
|
||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
import {Compiler, CompilerCache} from './compiler/compiler';
|
||||
|
|
|
@ -10,6 +10,8 @@ class Math {
|
|||
return math.pow(x, exponent);
|
||||
}
|
||||
|
||||
static num max(num a, num b) => math.max(a, b);
|
||||
|
||||
static num min(num a, num b) => math.min(a, b);
|
||||
|
||||
static num floor(num a) => a.floor();
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Temporary home of Material Design components for Angular 2.
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"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 %>",
|
||||
"dependencies": {
|
||||
"angular2": "<%= packageJson.version %>",
|
||||
"traceur": "<%= packageJson.dependencies.traceur %>",
|
||||
"rtts_assert": "<%= packageJson.version %>",
|
||||
"rx": "<%= packageJson.dependencies['rx'] %>",
|
||||
"zone.js": "<%= packageJson.dependencies['zone.js'] %>"
|
||||
},
|
||||
"devDependencies": <%= JSON.stringify(packageJson.devDependencies) %>
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
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.9.0-dev.8.0'
|
||||
dependencies:
|
||||
angular2: '^<%= packageJson.version %>'
|
||||
browser: '>=0.10.0 <0.11.0'
|
||||
dependency_overrides:
|
||||
angular2:
|
||||
path: ../angular2
|
|
@ -0,0 +1,2 @@
|
|||
<style>@import "angular2_material/src/components/button/button.css";</style>
|
||||
<span class="md-button-wrapper"><content></content></span>
|
|
@ -0,0 +1,47 @@
|
|||
import {Component, View} from 'angular2/angular2';
|
||||
import {PropertySetter, EventEmitter} from 'angular2/src/core/annotations/di';
|
||||
import {onChange} from 'angular2/src/core/annotations/annotations';
|
||||
import {isPresent, StringWrapper} from 'angular2/src/facade/lang';
|
||||
|
||||
|
||||
@Component({selector: '[md-button]:not([href])'})
|
||||
@View({templateUrl: 'angular2_material/src/components/button/button.html'})
|
||||
export class MdButton {
|
||||
// TODO(jelbourn): Ink ripples.
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: '[md-button][href]',
|
||||
properties: {
|
||||
'disabled': 'disabled'
|
||||
},
|
||||
hostListeners: {'click': 'onClick($event)'},
|
||||
lifecycle: [onChange]
|
||||
})
|
||||
@View({
|
||||
templateUrl: 'angular2_material/src/components/button/button.html'
|
||||
})
|
||||
export class MdAnchor {
|
||||
tabIndexSetter: Function;
|
||||
|
||||
/** Whether the component is disabled. */
|
||||
disabled: boolean;
|
||||
|
||||
constructor(@PropertySetter('tabIndex') tabIndexSetter: Function) {
|
||||
this.tabIndexSetter = tabIndexSetter;
|
||||
}
|
||||
|
||||
onClick(event) {
|
||||
// A disabled anchor shouldn't navigate anywhere.
|
||||
if (isPresent(this.disabled) && this.disabled !== false) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
/** Invoked when a change is detected. */
|
||||
onChange(_) {
|
||||
// A disabled anchor should not be in the tab flow.
|
||||
this.tabIndexSetter(this.disabled ? -1 : 0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,349 @@
|
|||
@import "../../core/style/variables";
|
||||
@import "../../core/style/shadows";
|
||||
|
||||
// TODO(jelbourn): This goes away.
|
||||
@import "../../core/style/default-theme";
|
||||
|
||||
$button-line-height: 25px !default;
|
||||
$button-padding: 2px 6px 3px !default;
|
||||
|
||||
// Fab buttons
|
||||
$button-fab-width: 56px !default;
|
||||
$button-fab-height: 56px !default;
|
||||
$button-fab-padding: 16px !default;
|
||||
$button-fab-mini-width: 40px !default;
|
||||
$button-fab-mini-height: 40px !default;
|
||||
|
||||
$button-fab-toast-offset: $button-fab-height * 0.75;
|
||||
|
||||
/**
|
||||
* Mixin to create distinct classes for fab positions, e.g. ".md-fab-bottom-right".
|
||||
*/
|
||||
@mixin fab-position($spot, $top: auto, $right: auto, $bottom: auto, $left: auto) {
|
||||
&.md-fab-#{$spot} {
|
||||
top: $top;
|
||||
right: $right;
|
||||
bottom: $bottom;
|
||||
left: $left;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
[md-button] {
|
||||
user-select: none;
|
||||
|
||||
// TODO(jelbourn): What canvas?
|
||||
position: relative; //for child absolute-positioned <canvas>
|
||||
|
||||
outline: none;
|
||||
border: 0;
|
||||
padding: 6px;
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
white-space: nowrap;
|
||||
|
||||
text-align: center;
|
||||
|
||||
// TODO(jelbourn): wat?
|
||||
font-weight: 500;
|
||||
font-style: inherit;
|
||||
font-variant: inherit;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
line-height: inherit;
|
||||
text-decoration: none;
|
||||
|
||||
cursor: pointer;
|
||||
overflow: hidden; // for ink containment
|
||||
|
||||
transition: box-shadow $swift-ease-out-duration $swift-ease-out-timing-function,
|
||||
background-color $swift-ease-out-duration $swift-ease-out-timing-function,
|
||||
transform $swift-ease-out-duration $swift-ease-out-timing-function;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&.md-cornered {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
&.md-icon {
|
||||
padding: 0;
|
||||
background: none;
|
||||
}
|
||||
|
||||
&.md-raised {
|
||||
transform: translate3d(0, 0, 0);
|
||||
|
||||
|
||||
&:not([disabled]) {
|
||||
@extend .md-shadow-bottom-z-1;
|
||||
}
|
||||
}
|
||||
|
||||
&.md-fab {
|
||||
// .md-fab-bottom-right
|
||||
@include fab-position(
|
||||
bottom-right,
|
||||
auto,
|
||||
($button-fab-width - $button-fab-padding) / 2,
|
||||
($button-fab-height - $button-fab-padding) / 2,
|
||||
auto);
|
||||
|
||||
// .md-fab-bottom-left
|
||||
@include fab-position(
|
||||
bottom-left,
|
||||
auto,
|
||||
auto,
|
||||
($button-fab-height - $button-fab-padding) / 2,
|
||||
($button-fab-width - $button-fab-padding) / 2);
|
||||
|
||||
// .md-fab-top-right
|
||||
@include fab-position(
|
||||
top-right,
|
||||
($button-fab-height - $button-fab-padding) / 2,
|
||||
($button-fab-width - $button-fab-padding) / 2,
|
||||
auto,
|
||||
auto);
|
||||
|
||||
// .md-fab-top-left
|
||||
@include fab-position(
|
||||
top-left,
|
||||
($button-fab-height - $button-fab-padding) / 2,
|
||||
auto,
|
||||
auto,
|
||||
($button-fab-width - $button-fab-padding) / 2);
|
||||
|
||||
|
||||
z-index: $z-index-fab;
|
||||
|
||||
width: $button-fab-width;
|
||||
height: $button-fab-height;
|
||||
|
||||
border-radius: 50%;
|
||||
|
||||
@extend .md-shadow-bottom-z-1;
|
||||
overflow: hidden;
|
||||
|
||||
transform: translate3d(0, 0, 0);
|
||||
|
||||
transition: 0.2s linear;
|
||||
transition-property: transform, box-shadow;
|
||||
|
||||
|
||||
// When there is an md-icon inside of an [md-button].
|
||||
& md-icon {
|
||||
line-height: $button-fab-height;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&.md-mini {
|
||||
width: $button-fab-mini-width;
|
||||
height: $button-fab-mini-height;
|
||||
md-icon {
|
||||
line-height: $button-fab-mini-height;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&:not([disabled]) {
|
||||
&.md-raised,
|
||||
&.md-fab {
|
||||
&:focus,
|
||||
&:hover {
|
||||
transform: translate3d(0, -1px, 0);
|
||||
@extend .md-shadow-bottom-z-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
.md-toast-open-top {
|
||||
[md-button].md-fab-top-left,
|
||||
[md-button].md-fab-top-right {
|
||||
transform: translate3d(0, $button-fab-toast-offset, 0);
|
||||
&:not([disabled]) {
|
||||
&:focus,
|
||||
&:hover {
|
||||
transform: translate3d(0, $button-fab-toast-offset - 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
.md-toast-open-bottom {
|
||||
[md-button].md-fab-bottom-left,
|
||||
[md-button].md-fab-bottom-right {
|
||||
transform: translate3d(0, -$button-fab-toast-offset, 0);
|
||||
&:not([disabled]) {
|
||||
&:focus,
|
||||
&:hover {
|
||||
transform: translate3d(0, -$button-fab-toast-offset - 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
.md-button-group {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// TODO
|
||||
.md-button-group > [md-button] {
|
||||
flex: 1;
|
||||
|
||||
display: block;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
width: 0;
|
||||
|
||||
border-width: 1px 0 1px 1px;
|
||||
border-radius: 0;
|
||||
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
&:first-child {
|
||||
border-radius: 2px 0 0 2px;
|
||||
}
|
||||
&:last-child {
|
||||
border-right-width: 1px;
|
||||
border-radius: 0 2px 2px 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------ Button theme ----------------------------------------------------------
|
||||
|
||||
$button-border-radius: 3px !default;
|
||||
$button-fab-border-radius: 50% !default;
|
||||
|
||||
// The ELEMENT '[md-button]' is the host.
|
||||
// The CLASS '[md-button]' is the shadow root.
|
||||
|
||||
md-toolbar [md-button].md-fab {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
|
||||
// Because of Shadow DOM emulation, the modifier classes are applied to the [md-button]
|
||||
// element (host), but the style needs to be changed for the shadow content (.[md-button]).
|
||||
[md-button] {
|
||||
border-radius: $button-border-radius;
|
||||
|
||||
// When the user explictly applies the primary color.
|
||||
&.md-primary {
|
||||
color: md-color($md-primary);
|
||||
}
|
||||
|
||||
&.md-primary.md-fab,
|
||||
&.md-primary.md-raised {
|
||||
color: md-color($md-primary, default-contrast);
|
||||
background-color: md-color($md-primary);
|
||||
}
|
||||
|
||||
// When the user explictly applies the accent color.
|
||||
&.md-accent {
|
||||
color: md-color($md-accent);
|
||||
}
|
||||
|
||||
&.md-accent.md-fab,
|
||||
&.md-accent.md-raised {
|
||||
color: md-color($md-accent, default-contrast);
|
||||
background-color: md-color($md-accent);
|
||||
}
|
||||
|
||||
// When the user explictly applies the warn color.
|
||||
&.md-warn {
|
||||
color: md-color($md-warn);
|
||||
}
|
||||
|
||||
&.md-warn.md-fab,
|
||||
&.md-warn.md-raised {
|
||||
color: md-color($md-warn, default-contrast);
|
||||
background-color: md-color($md-warn);
|
||||
}
|
||||
|
||||
// When the button is a fab without an explicit color applied.
|
||||
&.md-fab {
|
||||
border-radius: $button-fab-border-radius;
|
||||
background-color: md-color($md-accent);
|
||||
color: md-color($md-accent, default-contrast);
|
||||
}
|
||||
|
||||
// When the button is raised without an explicit color applied.
|
||||
&.md-raised {
|
||||
color: md-color($md-background, default-contrast);
|
||||
background-color: md-color($md-background, 50);
|
||||
}
|
||||
}
|
||||
|
||||
// Hover and focus styles (only applied when the button is not disabled).
|
||||
// The modifiers for :focus and :hover actually apply to the element in the
|
||||
// shadow DOM (the .[md-button]).
|
||||
[md-button]:not([disabled]) {
|
||||
// Default hover/focus background.
|
||||
&:focus,
|
||||
&:hover {
|
||||
background-color: md-color($md-background, 500, 0.2);
|
||||
}
|
||||
|
||||
&.md-primary.md-fab,
|
||||
&.md-primary.md-raised {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: md-color($md-primary, 600);
|
||||
}
|
||||
}
|
||||
|
||||
&.md-accent.md-fab,
|
||||
&.md-accent.md-raised {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: md-color($md-accent, 700);
|
||||
}
|
||||
}
|
||||
|
||||
&.md-warn.md-fab,
|
||||
&.md-warn.md-raised {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: md-color($md-warn, 700);
|
||||
}
|
||||
}
|
||||
|
||||
&.md-fab {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: md-color($md-accent, A700);
|
||||
}
|
||||
}
|
||||
|
||||
&.md-raised {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: md-color($md-background, 200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[md-button][disabled],
|
||||
[md-button][disabled].md-fab,
|
||||
[md-button][disabled].md-raised, {
|
||||
color: md-color($md-foreground, disabled);
|
||||
background-color: transparent;
|
||||
cursor: not-allowed;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<style>@import "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"><content></content></div>
|
||||
</div>
|
|
@ -0,0 +1,77 @@
|
|||
import {Component, View, Attribute, PropertySetter} from 'angular2/angular2';
|
||||
import {isPresent} from 'angular2/src/facade/lang';
|
||||
import {KeyCodes} from 'angular2_material/src/core/constants'
|
||||
|
||||
@Component({
|
||||
selector: 'md-checkbox',
|
||||
properties: {
|
||||
'checked': 'checked',
|
||||
'disabled': 'disabled'
|
||||
},
|
||||
hostListeners: {
|
||||
'keydown': 'onKeydown($event)'
|
||||
}
|
||||
})
|
||||
@View({
|
||||
templateUrl: 'angular2_material/src/components/checkbox/checkbox.html',
|
||||
directives: []
|
||||
})
|
||||
export class MdCheckbox {
|
||||
/** Whether this checkbox is checked. */
|
||||
checked_: boolean;
|
||||
|
||||
/** Setter for `aria-checked` attribute. */
|
||||
ariaCheckedSetter: Function;
|
||||
|
||||
/** Setter for `aria-disabled` attribute. */
|
||||
ariaDisabledSetter: Function;
|
||||
|
||||
constructor(
|
||||
@Attribute('tabindex') tabindex: string,
|
||||
@PropertySetter('tabindex') tabindexSetter: Function,
|
||||
@PropertySetter('attr.role') roleSetter: Function,
|
||||
@PropertySetter('attr.aria-checked') ariaCheckedSetter: Function,
|
||||
@PropertySetter('attr.aria-disabled') ariaDisabledSetter: Function) {
|
||||
this.ariaCheckedSetter = ariaCheckedSetter;
|
||||
this.ariaDisabledSetter = ariaDisabledSetter;
|
||||
|
||||
roleSetter('checkbox');
|
||||
this.checked = false;
|
||||
tabindexSetter(isPresent(tabindex) ? tabindex : '0');
|
||||
}
|
||||
|
||||
get checked() {
|
||||
return this.checked_;
|
||||
}
|
||||
|
||||
set checked(value) {
|
||||
this.checked_ = value;
|
||||
this.ariaCheckedSetter(value);
|
||||
}
|
||||
|
||||
get disabled() {
|
||||
return this.disabled_;
|
||||
}
|
||||
|
||||
set disabled(value) {
|
||||
this.disabled_ = isPresent(value) && value !== false;
|
||||
this.ariaDisabledSetter(this.disabled_);
|
||||
}
|
||||
|
||||
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;
|
||||
this.ariaCheckedSetter(this.checked);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
@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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<div class="md-grid-list">
|
||||
<div class="md-grid-tile">
|
||||
<figure></figure>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,253 @@
|
|||
import {Component, View, onAllChangesDone, Parent} from 'angular2/angular2';
|
||||
import {onDestroy, onChange} from 'angular2/src/core/annotations/annotations';
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {CONST} from 'angular2/src/facade/lang';
|
||||
import {isPresent, isString, NumberWrapper} from 'angular2/src/facade/lang';
|
||||
import {PropertySetter} from 'angular2/src/core/annotations/di';
|
||||
|
||||
// TODO(jelbourn): Set appropriate aria attributes for grid list elements.
|
||||
|
||||
@Component({
|
||||
selector: 'md-grid-list',
|
||||
properties: {
|
||||
'cols': 'cols',
|
||||
'gutterSize': 'gutter-size'
|
||||
},
|
||||
lifecycle: [onChange]
|
||||
})
|
||||
@View({
|
||||
templateUrl: 'angular2_material/src/components/grid_list/grid_list.html'
|
||||
})
|
||||
export class MdGridList {
|
||||
/** List of tiles that are being rendered. */
|
||||
tiles: Array<MdGridTile>;
|
||||
|
||||
/** Number of columns being rendered. Can be either string or number */
|
||||
cols;
|
||||
|
||||
/** Mode used to determine row heights. See RowHeightMode. */
|
||||
rowHeightMode: string;
|
||||
|
||||
/** Fixed row height, as given by the user. Only used for 'fixed' mode. */
|
||||
fixedRowHeight: number;
|
||||
|
||||
/** 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;
|
||||
|
||||
/** Array used to track the amount of space available. */
|
||||
spaceTracker: Array<number>;
|
||||
|
||||
constructor() {
|
||||
this.tiles = [];
|
||||
}
|
||||
|
||||
onAllChangesDone() {
|
||||
}
|
||||
|
||||
onChange(_) {
|
||||
if (!isPresent(this.spaceTracker)) {
|
||||
if (isString(this.cols)) {
|
||||
this.cols = NumberWrapper.parseIntAutoRadix(this.cols);
|
||||
}
|
||||
this.spaceTracker = ListWrapper.createFixedSize(this.cols);
|
||||
ListWrapper.fill(this.spaceTracker, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tile to the grid-list.
|
||||
* @param tile
|
||||
*/
|
||||
addTile(tile: MdGridTile) {
|
||||
ListWrapper.push(this.tiles, tile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a tile from the grid-list.
|
||||
* @param tile
|
||||
*/
|
||||
removeTile(tile: MdGridTile) {
|
||||
ListWrapper.remove(this.tiles, tile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change handler invoked when bindings are resolved or when bindings have changed.
|
||||
* Performs a layout.
|
||||
*/
|
||||
performLayout() {
|
||||
//console.log('laying out!');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 fration (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}) )`;
|
||||
}
|
||||
|
||||
|
||||
getTileStyle(tile: MdGridTile, rowIndex: number, colIndex: number): TileStyle {
|
||||
// Percent of the available horizontal space that one column takes up.
|
||||
var percentWidthPerTile = this.cols / 100;
|
||||
|
||||
// Fraction of the 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.
|
||||
var gutterWidthFractionPerTile = (this.cols - 1) / this.cols;
|
||||
|
||||
// Base horizontal size of a column.
|
||||
var baseTileWidth = 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.
|
||||
var tileStyle = new TileStyle();
|
||||
tileStyle.left = getTilePosition(baseTileWidth, colIndex);
|
||||
tileStyle.width = getTileSize(baseTileWidth, tile.colspan);
|
||||
|
||||
// TODO: make cases enums when we support enums
|
||||
switch (this.rowHeightMode) {
|
||||
case 'fixed':
|
||||
// In fixed mode, simply use the given row height.
|
||||
tileStyle.top = getTilePosition(this.fixedRowHeight, rowIndex);
|
||||
tileStyle.height = getTileSize(this.fixedRowHeight, tile.rowspan);
|
||||
break;
|
||||
|
||||
case 'ratio':
|
||||
var percentHeightPerTile = percentWidthPerTile / this.rowHeightRatio;
|
||||
let baseTileHeight = getBaseTileSize(percentHeightPerTile, gutterWidthFractionPerTile);
|
||||
|
||||
// Use paddingTop and marginTop to maintain the given aspect ratio, as
|
||||
// a percentage-based value for these properties is applied to the *width* of the
|
||||
// containing block. See http://www.w3.org/TR/CSS2/box.html#margin-properties
|
||||
tileStyle.marginTop = getTilePosition(baseTileHeight, rowIndex);
|
||||
tileStyle.paddingTop = getTileSize(baseTileHeight, tile.rowspan);
|
||||
break;
|
||||
|
||||
case 'fit':
|
||||
var percentHeightPerTile;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return tileStyle;
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'md-grid-tile',
|
||||
properties: {
|
||||
'rowspan': 'rowspan',
|
||||
'colspan': 'colspan'
|
||||
},
|
||||
lifecycle: [onDestroy, onChange]
|
||||
})
|
||||
@View({
|
||||
template: `<figure><content></content></figure>`
|
||||
})
|
||||
export class MdGridTile {
|
||||
gridList: MdGridList;
|
||||
rowspan: number;
|
||||
colspan: number;
|
||||
heightSetter;
|
||||
widthSetter;
|
||||
topSetter;
|
||||
leftSetter;
|
||||
marginTopSetter;
|
||||
paddingTopSetter;
|
||||
|
||||
isRegisteredWithGridList: boolean;
|
||||
|
||||
constructor(
|
||||
@Parent() gridList: MdGridList,
|
||||
@PropertySetter('style.height') heightSetter: Function,
|
||||
@PropertySetter('style.width') widthSetter: Function,
|
||||
@PropertySetter('style.top') topSetter: Function,
|
||||
@PropertySetter('style.left') leftSetter: Function,
|
||||
@PropertySetter('style.marginTop') marginTopSetter: Function,
|
||||
@PropertySetter('style.paddingTop') paddingTopSetter: Function,
|
||||
@PropertySetter('role') roleSetter: Function
|
||||
) {
|
||||
this.gridList = gridList;
|
||||
this.heightSetter = heightSetter;
|
||||
this.widthSetter = widthSetter;
|
||||
this.topSetter = topSetter;
|
||||
this.leftSetter = leftSetter;
|
||||
this.marginTopSetter = marginTopSetter;
|
||||
this.paddingTopSetter = paddingTopSetter;
|
||||
roleSetter('listitem');
|
||||
|
||||
// Tiles default to 1x1, but rowspan and colspan can be changed via binding.
|
||||
this.rowspan = 1;
|
||||
this.colspan = 1;
|
||||
|
||||
// DEBUG
|
||||
heightSetter(`${gridList.tiles.length * 100}px`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change handler invoked when bindings are resolved or when bindings have changed.
|
||||
* Notifies grid-list that a re-layout is required.
|
||||
*/
|
||||
onChange(_) {
|
||||
//console.log(`grid-tile on-change ${this.gridList.tiles.indexOf(this)}`);
|
||||
if (!this.isRegisteredWithGridList) {
|
||||
this.gridList.addTile(this);
|
||||
this.isRegisteredWithGridList = true;
|
||||
} else {
|
||||
this.gridList.performLayout();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor function. Deregisters this tile from the containing grid-list.
|
||||
*/
|
||||
onDestroy() {
|
||||
this.gridList.removeTile(this);
|
||||
}
|
||||
}
|
||||
|
||||
/** 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;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import {Decorator} from 'angular2/angular2';
|
||||
import {PropertySetter} from 'angular2/src/core/annotations/di';
|
||||
|
||||
@Decorator({
|
||||
selector: 'md-input-container input'
|
||||
})
|
||||
export class MdInput {
|
||||
constructor() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Decorator({
|
||||
selector: 'md-input-container'
|
||||
})
|
||||
export class MdInputContainer {
|
||||
}
|
|
@ -0,0 +1,257 @@
|
|||
@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%);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<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>
|
14
modules/angular2_material/src/components/progress-circular/progress_circular.js
vendored
Normal file
14
modules/angular2_material/src/components/progress-circular/progress_circular.js
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
import {Component, View} from 'angular2/angular2';
|
||||
import {isPresent} from 'angular2/src/facade/lang';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'md-progress-circular'
|
||||
})
|
||||
@View({
|
||||
templateUrl: 'angular2_material/src/components/progress-circular/progress_circular.html'
|
||||
})
|
||||
export class MdProgressCircular {
|
||||
constructor() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<style>@import "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>
|
|
@ -0,0 +1,98 @@
|
|||
import {Component, View, Attribute, PropertySetter, onChange} from 'angular2/angular2';
|
||||
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||
import {Math} from 'angular2/src/facade/math';
|
||||
|
||||
@Component({
|
||||
selector: 'md-progress-linear',
|
||||
lifecycle: [onChange],
|
||||
properties: {
|
||||
'value': 'value',
|
||||
'bufferValue': 'buffer-value'
|
||||
}
|
||||
})
|
||||
@View({
|
||||
templateUrl: 'angular2_material/src/components/progress-linear/progress_linear.html',
|
||||
directives: []
|
||||
})
|
||||
export class MdProgressLinear {
|
||||
/** Value for the primary bar. */
|
||||
value_: number;
|
||||
|
||||
/** Value for the secondary bar. */
|
||||
bufferValue: number;
|
||||
|
||||
/** The render mode for the progress bar. */
|
||||
mode: string;
|
||||
|
||||
/** Attribute setter for aria-valuenow. */
|
||||
ariaValueNowSetter: Function;
|
||||
|
||||
/** CSS `transform` property applied to the primary bar. */
|
||||
primaryBarTransform: string;
|
||||
|
||||
/** CSS `transform` property applied to the secondary bar. */
|
||||
secondaryBarTransform: string;
|
||||
|
||||
constructor(
|
||||
@Attribute('md-mode') mode: string,
|
||||
@PropertySetter('attr.role') roleSetter: Function,
|
||||
@PropertySetter('attr.aria-valuemin') ariaValueMinSetter: Function,
|
||||
@PropertySetter('attr.aria-valuemax') ariaValueMaxSetter: Function,
|
||||
@PropertySetter('attr.aria-valuenow') ariaValueNowSetter: Function) {
|
||||
this.ariaValueNowSetter = ariaValueNowSetter;
|
||||
this.primaryBarTransform = '';
|
||||
this.secondaryBarTransform = '';
|
||||
|
||||
roleSetter('progressbar');
|
||||
ariaValueMinSetter('0');
|
||||
ariaValueMaxSetter('100');
|
||||
|
||||
this.mode = isPresent(mode) ? mode : Mode.DETERMINATE;
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this.value_;
|
||||
}
|
||||
|
||||
set value(v) {
|
||||
if (isPresent(v)) {
|
||||
this.value_ = MdProgressLinear.clamp(v);
|
||||
this.ariaValueNowSetter(this.value_);
|
||||
}
|
||||
}
|
||||
|
||||
onChange(_) {
|
||||
// If the mode does not use a value, or if there is no value, do nothing.
|
||||
if (this.mode == Mode['QUERY'] || this.mode == Mode['INDETERMINATE'] || isBlank(this.value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.primaryBarTransform = this.transformForValue(this.value);
|
||||
|
||||
// The bufferValue is only used in buffer mode.
|
||||
if (this.mode == Mode['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.
|
||||
var scale = value / 100;
|
||||
var 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));
|
||||
}
|
||||
}
|
||||
|
||||
/** @enum {string} Progress-linear modes. */
|
||||
var Mode = {
|
||||
'DETERMINATE': 'determinate',
|
||||
'INDETERMINATE': 'indeterminate',
|
||||
'BUFFER': 'buffer',
|
||||
'QUERY': 'query'
|
||||
};
|
|
@ -0,0 +1,266 @@
|
|||
@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%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
@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: 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 <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;
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
md-radio-group {
|
||||
border: 1px dotted transparent;
|
||||
display: block;
|
||||
outline: none;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<style>@import "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-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">
|
||||
<content></content>
|
||||
</div>
|
||||
</label>
|
|
@ -0,0 +1,341 @@
|
|||
import {Component, View, Parent, Ancestor, Attribute, PropertySetter,
|
||||
EventEmitter} from 'angular2/angular2';
|
||||
import {Optional} from 'angular2/src/di/annotations';
|
||||
import {MdRadioDispatcher} from 'angular2_material/src/components/radio/radio_dispatcher'
|
||||
import {MdTheme} from 'angular2_material/src/core/theme'
|
||||
import {onChange} from 'angular2/src/core/annotations/annotations';
|
||||
import {isPresent, StringWrapper} from 'angular2/src/facade/lang';
|
||||
// import {KeyCodes} from 'angular2_material/src/core/constants'
|
||||
import {Math} from 'angular2/src/facade/math';
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
// 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-button',
|
||||
lifecycle: [onChange],
|
||||
properties: {
|
||||
'id': 'id',
|
||||
'name': 'name',
|
||||
'value': 'value',
|
||||
'checked': 'checked',
|
||||
'disabled': 'disabled'
|
||||
},
|
||||
hostListeners: {
|
||||
'keydown': 'onKeydown($event)'
|
||||
}
|
||||
})
|
||||
@View({
|
||||
templateUrl: 'angular2_material/src/components/radio/radio_button.html',
|
||||
directives: []
|
||||
})
|
||||
export class MdRadioButton {
|
||||
/** 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;
|
||||
|
||||
/** Setter for `aria-checked` attribute. */
|
||||
ariaCheckedSetter: Function;
|
||||
|
||||
/** Setter for `aria-disabled` attribute. */
|
||||
ariaDisabledSetter: Function;
|
||||
|
||||
constructor(
|
||||
@Optional() @Parent() radioGroup: MdRadioGroup,
|
||||
@Attribute('id') id: string,
|
||||
@Attribute('tabindex') tabindex: string,
|
||||
@PropertySetter('id') idSetter: Function,
|
||||
@PropertySetter('tabindex') tabindexSetter: Function,
|
||||
@PropertySetter('attr.role') roleSetter: Function,
|
||||
@PropertySetter('attr.aria-checked') ariaCheckedSetter: Function,
|
||||
@PropertySetter('attr.aria-disabled') ariaDisabledSetter: Function,
|
||||
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.ariaCheckedSetter = ariaCheckedSetter;
|
||||
this.ariaDisabledSetter = ariaDisabledSetter;
|
||||
this.value = null;
|
||||
|
||||
roleSetter('radio');
|
||||
this.checked = false;
|
||||
|
||||
this.id = isPresent(id) ? id : `md-radio-${_uniqueIdCounter++}`;
|
||||
idSetter(this.id);
|
||||
|
||||
// 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)) {
|
||||
tabindexSetter(isPresent(tabindex) ? tabindex : '0');
|
||||
}
|
||||
}
|
||||
|
||||
/** Change handler invoked when bindings are resolved or when bindings have changed. */
|
||||
onChange(_) {
|
||||
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 checked() {
|
||||
return this.checked_;
|
||||
}
|
||||
|
||||
set checked(value) {
|
||||
this.checked_ = value;
|
||||
this.ariaCheckedSetter(value);
|
||||
}
|
||||
|
||||
get disabled() {
|
||||
return this.disabled_;
|
||||
}
|
||||
|
||||
set disabled(value) {
|
||||
this.disabled_ = isPresent(value) && value !== false;
|
||||
this.ariaDisabledSetter(this.disabled_);
|
||||
}
|
||||
|
||||
/** 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 (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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'md-radio-group',
|
||||
lifecycle: [onChange],
|
||||
properties: {
|
||||
'disabled': 'disabled',
|
||||
'value': 'value'
|
||||
},
|
||||
hostListeners: {
|
||||
'keydown': 'onKeydown($event)'
|
||||
}
|
||||
})
|
||||
@View({
|
||||
templateUrl: 'angular2_material/src/components/radio/radio_group.html'
|
||||
})
|
||||
export class MdRadioGroup {
|
||||
/** 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;
|
||||
|
||||
/** List of child radio buttons. */
|
||||
radios_: List<MdRadioButton>;
|
||||
|
||||
changeEmitter: Function;
|
||||
|
||||
ariaActiveDescendantSetter: Function;
|
||||
|
||||
ariaDisabledSetter: Function;
|
||||
|
||||
disabled_: boolean;
|
||||
|
||||
/** The ID of the selected radio button. */
|
||||
selectedRadioId: string;
|
||||
|
||||
constructor(
|
||||
@Attribute('tabindex') tabindex: string,
|
||||
@Attribute('disabled') disabled: string,
|
||||
@PropertySetter('tabindex') tabindexSetter: Function,
|
||||
@PropertySetter('attr.role') roleSetter: Function,
|
||||
@PropertySetter('attr.aria-disabled') ariaDisabledSetter: Function,
|
||||
@PropertySetter('attr.aria-activedescendant') ariaActiveDescendantSetter: Function,
|
||||
@EventEmitter('change') changeEmitter: Function,
|
||||
radioDispatcher: MdRadioDispatcher) {
|
||||
this.name_ = `md-radio-group-${_uniqueIdCounter++}`;
|
||||
this.radios_ = [];
|
||||
this.changeEmitter = changeEmitter;
|
||||
this.ariaActiveDescendantSetter = ariaActiveDescendantSetter;
|
||||
this.ariaDisabledSetter = ariaDisabledSetter;
|
||||
this.radioDispatcher = radioDispatcher;
|
||||
this.selectedRadioId = '';
|
||||
this.disabled_ = false;
|
||||
|
||||
roleSetter('radiogroup');
|
||||
|
||||
// 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).
|
||||
tabindexSetter(isPresent(tabindex) ? tabindex : '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;
|
||||
this.ariaDisabledSetter(this.disabled_);
|
||||
}
|
||||
|
||||
/** Change handler invoked when bindings are resolved or when bindings have changed. */
|
||||
onChange(_) {
|
||||
// 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_);
|
||||
ListWrapper.forEach(this.radios_, (radio) => {
|
||||
if (radio.value == this.value) {
|
||||
radio.checked = true;
|
||||
this.selectedRadioId = radio.id;
|
||||
this.ariaActiveDescendantSetter(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.ariaActiveDescendantSetter(id);
|
||||
this.changeEmitter();
|
||||
}
|
||||
|
||||
/** Registers a child radio button with this group. */
|
||||
register(radio: MdRadioButton) {
|
||||
ListWrapper.push(this.radios_, 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:
|
||||
case 38:
|
||||
this.stepSelectedRadio(-1);
|
||||
event.preventDefault();
|
||||
break;
|
||||
//case KeyCodes.DOWN:
|
||||
case 40:
|
||||
this.stepSelectedRadio(1);
|
||||
event.preventDefault();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(jelbourn): Replace this with a findIndex method in the collections facade.
|
||||
getSelectedRadioIndex(): number {
|
||||
for (var 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) {
|
||||
var index = this.getSelectedRadioIndex() + step;
|
||||
if (index < 0 || index >= this.radios_.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
var 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;
|
||||
|
||||
this.value = radio.value;
|
||||
this.selectedRadioId = radio.id;
|
||||
this.ariaActiveDescendantSetter(radio.id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
/**
|
||||
* Class for radio buttons to coordinate unique selection based on name.
|
||||
* Indended to be consumed as an Angular service.
|
||||
*/
|
||||
export class MdRadioDispatcher {
|
||||
// TODO(jelbourn): Change this to TypeScript syntax when supported.
|
||||
listeners_: Array<Function>;
|
||||
|
||||
constructor() {
|
||||
this.listeners_ = [];
|
||||
}
|
||||
|
||||
/** Notify other nadio buttons that selection for the given name has been set. */
|
||||
notify(name: string) {
|
||||
ListWrapper.forEach(this.listeners_, (f) => f(name));
|
||||
}
|
||||
|
||||
/** Listen for future changes to radio button selection. */
|
||||
listen(listener) {
|
||||
ListWrapper.push(this.listeners_, listener);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
<style>@import "angular2_material/src/components/radio/radio-group.css";</style>
|
||||
<content></content>
|
|
@ -0,0 +1,11 @@
|
|||
<style>@import "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"><content></content></div>
|
||||
</div>
|
|
@ -0,0 +1,80 @@
|
|||
import {Component, View, Attribute, PropertySetter} from 'angular2/angular2';
|
||||
import {isPresent} from 'angular2/src/facade/lang';
|
||||
import {KeyCodes} from 'angular2_material/src/core/constants'
|
||||
|
||||
// TODO(jelbourn): without gesture support, this is identical to MdCheckbox.
|
||||
|
||||
@Component({
|
||||
selector: 'md-switch',
|
||||
properties: {
|
||||
'checked': 'checked',
|
||||
'disabled': 'disabled'
|
||||
},
|
||||
hostListeners: {
|
||||
'keydown': 'onKeydown($event)'
|
||||
}
|
||||
})
|
||||
@View({
|
||||
templateUrl: 'angular2_material/src/components/switcher/switch.html',
|
||||
directives: []
|
||||
})
|
||||
export class MdSwitch {
|
||||
/** Whether this switch is checked. */
|
||||
checked_: boolean;
|
||||
|
||||
/** Setter for `aria-checked` attribute. */
|
||||
ariaCheckedSetter: Function;
|
||||
|
||||
/** Setter for `aria-disabled` attribute. */
|
||||
ariaDisabledSetter: Function;
|
||||
|
||||
constructor(
|
||||
@Attribute('tabindex') tabindex: string,
|
||||
@PropertySetter('tabindex') tabindexSetter: Function,
|
||||
@PropertySetter('attr.role') roleSetter: Function,
|
||||
@PropertySetter('attr.aria-checked') ariaCheckedSetter: Function,
|
||||
@PropertySetter('attr.aria-disabled') ariaDisabledSetter: Function) {
|
||||
this.ariaCheckedSetter = ariaCheckedSetter;
|
||||
this.ariaDisabledSetter = ariaDisabledSetter;
|
||||
|
||||
roleSetter('checkbox');
|
||||
this.checked = false;
|
||||
tabindexSetter(isPresent(tabindex) ? tabindex : '0');
|
||||
}
|
||||
|
||||
get checked() {
|
||||
return this.checked_;
|
||||
}
|
||||
|
||||
set checked(value) {
|
||||
this.checked_ = value;
|
||||
this.ariaCheckedSetter(value);
|
||||
}
|
||||
|
||||
get disabled() {
|
||||
return this.disabled_;
|
||||
}
|
||||
|
||||
set disabled(value) {
|
||||
this.disabled_ = isPresent(value) && value !== false;
|
||||
this.ariaDisabledSetter(this.disabled_);
|
||||
}
|
||||
|
||||
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;
|
||||
this.ariaCheckedSetter(this.checked);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
@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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
// TODO: this is not how TS&Dart enums are defined and it definitely won't
|
||||
// work in Dart. Switch to proper enums when we support them.
|
||||
//export var KeyCodes = {
|
||||
// SPACE: 32,
|
||||
// UP: 38,
|
||||
// DOWN: 40
|
||||
//};
|
|
@ -0,0 +1,13 @@
|
|||
@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);
|
|
@ -0,0 +1,666 @@
|
|||
// 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,
|
||||
),
|
||||
);
|
|
@ -0,0 +1,9 @@
|
|||
// 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 {
|
||||
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
|
||||
}
|
||||
|
||||
.md-shadow-bottom-z-2 {
|
||||
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4);
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
// ** 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
|
||||
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
// 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;
|
||||
|
||||
|
||||
// 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;
|
|
@ -0,0 +1,12 @@
|
|||
import {Decorator} from 'angular2/angular2';
|
||||
|
||||
@Decorator({
|
||||
selector: '[md-theme]'
|
||||
})
|
||||
export class MdTheme {
|
||||
color: string;
|
||||
|
||||
constructor() {
|
||||
this.color = 'sky-blue'
|
||||
}
|
||||
}
|
|
@ -3,10 +3,13 @@ environment:
|
|||
sdk: '>=1.4.0'
|
||||
dependencies:
|
||||
angular2: '^<%= packageJson.version %>'
|
||||
angular2_material: '^<%= packageJson.version %>'
|
||||
browser: '>=0.10.0 <0.11.0'
|
||||
dependency_overrides:
|
||||
angular2:
|
||||
path: ../angular2
|
||||
angular2_material:
|
||||
path: ../angular2_material
|
||||
dev_dependencies:
|
||||
guinness: ">=0.1.17 <0.2.0"
|
||||
benchpress:
|
||||
|
@ -16,7 +19,7 @@ transformers:
|
|||
entry_points: web/src/hello_world/index_common.dart
|
||||
reflection_entry_points: web/src/hello_world/index.dart
|
||||
- $dart2js:
|
||||
minify: true
|
||||
commandLineOptions: [--trust-type-annotations, --trust-primitives, --dump-info]
|
||||
minify: false
|
||||
#commandLineOptions: [--trust-type-annotations, --trust-primitives, --dump-info]
|
||||
#commandLineOptions: [--trust-type-annotations, --dump-info]
|
||||
#commandLineOptions: [--dump-info]
|
||||
commandLineOptions: [--dump-info]
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
<style>
|
||||
section {
|
||||
background: #f7f7f7;
|
||||
border-radius: 3px;
|
||||
text-align: center;
|
||||
margin: 1em;
|
||||
position: relative !important;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
section [md-button]:not(.md-fab) {
|
||||
min-width: 10em;
|
||||
}
|
||||
section [md-button] {
|
||||
display: inline-block;
|
||||
margin: 1em;
|
||||
line-height: 25px;
|
||||
}
|
||||
.label {
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
left: 7px;
|
||||
color: #ccc;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h1>Button demo</h1>
|
||||
|
||||
<p>
|
||||
You just clicked: <span>{{previousClick}}</span>
|
||||
</p>
|
||||
|
||||
<section>
|
||||
<form (^submit)="submit('form submit')">
|
||||
<button md-button>SUBMIT</button>
|
||||
<button>Native button</button>
|
||||
</form>
|
||||
|
||||
<span class="label">form submit</span>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<span class="label">Regular button</span>
|
||||
|
||||
<button md-button (^click)="click('button')">BUTTON</button>
|
||||
|
||||
<button md-button class="md-primary" (^click)="click('primary')">PRIMARY</button>
|
||||
<button md-button disabled="disabled" (^click)="click('disabled')">DISABLED</button>
|
||||
<button md-button class="md-accent" (^click)="click('accent')">ACCENT</button>
|
||||
<button md-button class="md-warn" (^click)="click('warn')">WARN</button>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<span class="label">Raised button</span>
|
||||
<button md-button class="md-raised" (^click)="click('raised')">BUTTON</button>
|
||||
<button md-button class="md-raised md-primary" (^click)="click('raised primary')">PRIMARY</button>
|
||||
<button md-button class="md-raised" disabled="disabled" (^click)="click('raised disabled')">DISABLED</button>
|
||||
<button md-button class="md-raised md-accent" (^click)="click('raised accent')">ACCENT</button>
|
||||
<button md-button class="md-raised md-warn" (^click)="click('raised warn')">WARN</button>
|
||||
</section>
|
||||
<section>
|
||||
<span class="label">Fab button</span>
|
||||
<button md-button class="md-fab" (^click)="click('fab')">BTN</button>
|
||||
<button md-button class="md-fab md-primary" (^click)="click('fab primary')">PRMY</button>
|
||||
<button md-button class="md-fab" disabled="disabled" (^click)="click('fab disabled')">DIS</button>
|
||||
<button md-button class="md-fab md-accent" (^click)="click('fab accent')">ACC</button>
|
||||
<button md-button class="md-fab md-warn" (^click)="click('fab warn')">WRN</button>
|
||||
</section>
|
||||
<section>
|
||||
<span class="label">Anchor / hyperlink</span>
|
||||
<a md-button href="http://google.com" target="_blank">HREF</a>
|
||||
<a md-button href="http://google.com" disabled>DISABLED HREF</a>
|
||||
<a md-button class="md-raised" target="_blank" href="http://google.com">RAISED HREF</a>
|
||||
</section>
|
||||
|
||||
|
||||
<p template="for #item of items">
|
||||
Repeated button:
|
||||
<button md-button tabindex="-1" (^click)="increment()">{{action}}</button>
|
||||
{{clickCount}}
|
||||
</p>
|
|
@ -0,0 +1,16 @@
|
|||
<!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>
|
|
@ -0,0 +1,46 @@
|
|||
import {bootstrap, Component, View, MapWrapper, ListWrapper, For} from 'angular2/angular2';
|
||||
import {MdButton, MdAnchor} from 'angular2_material/src/components/button/button'
|
||||
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
||||
import {bind} from 'angular2/di';
|
||||
|
||||
@Component({
|
||||
selector: 'demo-app'
|
||||
})
|
||||
@View({
|
||||
templateUrl: './demo_app.html',
|
||||
directives: [MdButton, MdAnchor, For]
|
||||
})
|
||||
class DemoApp {
|
||||
previousClick: string;
|
||||
action: string;
|
||||
clickCount: number;
|
||||
items: List<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, [
|
||||
bind(UrlResolver).toValue(new DemoUrlResolver())
|
||||
]);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<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>
|
|
@ -0,0 +1,18 @@
|
|||
<!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>
|
||||
|
||||
$SCRIPTS$
|
||||
<demo-app>Loading...</demo-app>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,31 @@
|
|||
import {bootstrap, Component, View} from 'angular2/angular2';
|
||||
import {MdCheckbox} from 'angular2_material/src/components/checkbox/checkbox'
|
||||
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
||||
import {bind} from 'angular2/di';
|
||||
|
||||
@Component({
|
||||
selector: 'demo-app'
|
||||
})
|
||||
@View({
|
||||
templateUrl: './demo_app.html',
|
||||
directives: [MdCheckbox]
|
||||
})
|
||||
class DemoApp {
|
||||
toggleCount: number;
|
||||
|
||||
constructor() {
|
||||
this.toggleCount = 0;
|
||||
}
|
||||
|
||||
increment() {
|
||||
this.toggleCount++;
|
||||
}
|
||||
}
|
||||
|
||||
export function main() {
|
||||
commonDemoSetup();
|
||||
bootstrap(DemoApp, [
|
||||
bind(UrlResolver).toValue(new DemoUrlResolver())
|
||||
]);
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
import {IMPLEMENTS, print} from 'angular2/src/facade/lang';
|
||||
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||
import {isPresent, isBlank, RegExpWrapper, StringWrapper, BaseException} from 'angular2/src/facade/lang';
|
||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
import {Injectable} from 'angular2/di';
|
||||
import {ReflectionCapabilities} from 'angular2/src/reflection/reflection_capabilities';
|
||||
import {reflector} from 'angular2/src/reflection/reflection';
|
||||
import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter';
|
||||
|
||||
export function commonDemoSetup(): void {
|
||||
BrowserDomAdapter.makeCurrent();
|
||||
reflector.reflectionCapabilities = new ReflectionCapabilities();
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
@IMPLEMENTS(UrlResolver)
|
||||
export class DemoUrlResolver {
|
||||
static a;
|
||||
|
||||
isInPubServe:boolean;
|
||||
|
||||
constructor() {
|
||||
if (isBlank(UrlResolver.a)) {
|
||||
UrlResolver.a = DOM.createElement('a');
|
||||
}
|
||||
this.isInPubServe = _isInPubServe();
|
||||
}
|
||||
|
||||
resolve(baseUrl: string, url: string): string {
|
||||
if (isBlank(baseUrl)) {
|
||||
DOM.resolveAndSetHref(UrlResolver.a, url, null);
|
||||
return DOM.getHref(UrlResolver.a);
|
||||
}
|
||||
|
||||
if (isBlank(url) || url == '') return baseUrl;
|
||||
|
||||
if (url[0] == '/') {
|
||||
throw new BaseException(`Could not resolve the url ${url} from ${baseUrl}`);
|
||||
}
|
||||
|
||||
var m = RegExpWrapper.firstMatch(_schemeRe, url);
|
||||
|
||||
if (isPresent(m[1])) {
|
||||
return url;
|
||||
}
|
||||
|
||||
if (StringWrapper.startsWith(url, './')) {
|
||||
return `${baseUrl}/${url}`;
|
||||
}
|
||||
|
||||
if (this.isInPubServe) {
|
||||
return `/packages/${url}`;
|
||||
} else {
|
||||
return `/${url}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var _schemeRe = RegExpWrapper.create('^([^:/?#]+:)?');
|
||||
|
||||
// TODO: remove this hack when http://dartbug.com/23128 is fixed
|
||||
function _isInPubServe():boolean {
|
||||
try {
|
||||
int.parse('123');
|
||||
print('>> Running in Dart');
|
||||
return true;
|
||||
} catch(_) {
|
||||
print('>> Running in JS');
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<style>@import "angular2_material/src/components/grid_list/grid-list.css";</style>
|
||||
|
||||
<style>
|
||||
md-grid-tile {
|
||||
background-color: lightblue;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div>
|
||||
|
||||
<h2>grid-list demo</h2>
|
||||
|
||||
<md-grid-list cols="5" gutter-size="2em">
|
||||
|
||||
<md-grid-tile cols="5">
|
||||
Tile #1
|
||||
</md-grid-tile>
|
||||
|
||||
<md-grid-tile rowspan="2" colspan="2">
|
||||
Tile #2
|
||||
</md-grid-tile>
|
||||
|
||||
<md-grid-tile [rowspan]="tile3RowSpan" [colspan]="tile3RowSpan">
|
||||
Tile #3
|
||||
</md-grid-tile>
|
||||
|
||||
</md-grid-list>
|
||||
|
||||
</div>
|
|
@ -0,0 +1,20 @@
|
|||
<!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>
|
||||
|
||||
$SCRIPTS$
|
||||
|
||||
<demo-app>Loading...</demo-app>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,30 @@
|
|||
import {bootstrap, Component, View} from 'angular2/angular2';
|
||||
import {MdGridList, MdGridTile} from 'angular2_material/src/components/grid_list/grid_list'
|
||||
import {MdTheme} from 'angular2_material/src/core/theme'
|
||||
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
||||
import {bind} from 'angular2/di';
|
||||
|
||||
@Component({
|
||||
selector: 'demo-app'
|
||||
})
|
||||
@View({
|
||||
templateUrl: './demo_app.html',
|
||||
directives: [MdGridList, MdGridTile]
|
||||
})
|
||||
class DemoApp {
|
||||
tile3RowSpan: number;
|
||||
tile3ColSpan: number;
|
||||
|
||||
constructor() {
|
||||
this.tile3RowSpan = 3;
|
||||
this.tile3ColSpan = 3;
|
||||
}
|
||||
}
|
||||
|
||||
export function main() {
|
||||
commonDemoSetup();
|
||||
bootstrap(DemoApp, [
|
||||
bind(UrlResolver).toValue(new DemoUrlResolver())
|
||||
]);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<style>@import "angular2_material/src/components/input/input.css";</style>
|
||||
<div md-theme="default">
|
||||
<h2>input demo</h2>
|
||||
|
||||
<md-input-container>
|
||||
<label>Name</label>
|
||||
<input>
|
||||
</md-input-container>
|
||||
|
||||
</div>
|
|
@ -0,0 +1,19 @@
|
|||
<!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>
|
||||
|
||||
$SCRIPTS$
|
||||
|
||||
<demo-app>Loading...</demo-app>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,31 @@
|
|||
import {bootstrap, Component, View} from 'angular2/angular2';
|
||||
import {MdCheckbox} from 'angular2_material/src/components/checkbox/checkbox'
|
||||
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
||||
import {bind} from 'angular2/di';
|
||||
|
||||
@Component({
|
||||
selector: 'demo-app'
|
||||
})
|
||||
@View({
|
||||
templateUrl: './demo_app.html',
|
||||
directives: [MdCheckbox]
|
||||
})
|
||||
class DemoApp {
|
||||
toggleCount: number;
|
||||
|
||||
constructor() {
|
||||
this.toggleCount = 0;
|
||||
}
|
||||
|
||||
increment() {
|
||||
this.toggleCount++;
|
||||
}
|
||||
}
|
||||
|
||||
export function main() {
|
||||
commonDemoSetup();
|
||||
bootstrap(DemoApp, [
|
||||
bind(UrlResolver).toValue(new DemoUrlResolver())
|
||||
]);
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
<link>
|
||||
|
||||
<div style="width: 500px;">
|
||||
<h2>Progress-linear demo</h2>
|
||||
|
||||
<p>
|
||||
Determinate: primary
|
||||
<md-progress-linear md-mode="determinate" [value]="progress" class="md-accent">
|
||||
</md-progress-linear>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Determinate: accent
|
||||
<md-progress-linear md-mode="determinate" [value]="progress" class="md-primary">
|
||||
</md-progress-linear>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Buffer
|
||||
<md-progress-linear md-mode="buffer"
|
||||
[value]="progress" [buffer-value]="progress + (200 / progress)" class="md-warn">
|
||||
</md-progress-linear>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Indeterminate
|
||||
<md-progress-linear md-mode="indeterminate" class="md-primary">
|
||||
</md-progress-linear>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Query
|
||||
<md-progress-linear md-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)">Increment</button>
|
||||
<button type="button" (click)="step(-10)">Decrement</button>
|
||||
</div>
|
|
@ -0,0 +1,18 @@
|
|||
<!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>
|
||||
|
||||
$SCRIPTS$
|
||||
<demo-app>Loading...</demo-app>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,31 @@
|
|||
import {bootstrap, Component, View} from 'angular2/angular2';
|
||||
import {MdProgressLinear} from 'angular2_material/src/components/progress-linear/progress_linear'
|
||||
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
||||
import {bind} from 'angular2/di';
|
||||
|
||||
@Component({
|
||||
selector: 'demo-app'
|
||||
})
|
||||
@View({
|
||||
templateUrl: './demo_app.html',
|
||||
directives: [MdProgressLinear]
|
||||
})
|
||||
class DemoApp {
|
||||
progress: number;
|
||||
|
||||
constructor() {
|
||||
this.progress = 40;
|
||||
}
|
||||
|
||||
step(s: number) {
|
||||
this.progress += s;
|
||||
}
|
||||
}
|
||||
|
||||
export function main() {
|
||||
commonDemoSetup();
|
||||
bootstrap(DemoApp, [
|
||||
bind(UrlResolver).toValue(new DemoUrlResolver())
|
||||
]);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<div>
|
||||
<h2>Radio buttons</h2>
|
||||
<h3>Inside of a radiogroup</h3>
|
||||
|
||||
<md-radio-group #scifi (change)="onGroupChange()">
|
||||
<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()">Wind</md-radio-button>
|
||||
<md-radio-button name="element" (^click)="onIndividualClick()" disabled>Heart (disabled)</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>
|
|
@ -0,0 +1,20 @@
|
|||
<!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>
|
||||
|
||||
$SCRIPTS$
|
||||
|
||||
<demo-app>Loading...</demo-app>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,49 @@
|
|||
import {bootstrap, Component, View} from 'angular2/angular2';
|
||||
import {MdRadioButton, MdRadioGroup} from 'angular2_material/src/components/radio/radio_button'
|
||||
import {MdRadioDispatcher} from 'angular2_material/src/components/radio/radio_dispatcher'
|
||||
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
||||
import {bind} from 'angular2/di';
|
||||
|
||||
@Component({
|
||||
selector: 'demo-app',
|
||||
injectables: [MdRadioDispatcher]
|
||||
})
|
||||
@View({
|
||||
templateUrl: './demo_app.html',
|
||||
directives: [MdRadioGroup, MdRadioButton]
|
||||
})
|
||||
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, [
|
||||
bind(UrlResolver).toValue(new DemoUrlResolver())
|
||||
]);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<div md-theme="default">
|
||||
<h2>Switch 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>
|
|
@ -0,0 +1,19 @@
|
|||
<!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>
|
||||
|
||||
$SCRIPTS$
|
||||
|
||||
<demo-app>Loading...</demo-app>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,31 @@
|
|||
import {bootstrap, Component, View} from 'angular2/angular2';
|
||||
import {MdSwitch} from 'angular2_material/src/components/switcher/switch'
|
||||
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
||||
import {bind} from 'angular2/di';
|
||||
|
||||
@Component({
|
||||
selector: 'demo-app'
|
||||
})
|
||||
@View({
|
||||
templateUrl: './demo_app.html',
|
||||
directives: [MdSwitch]
|
||||
})
|
||||
class DemoApp {
|
||||
toggleCount: number;
|
||||
|
||||
constructor() {
|
||||
this.toggleCount = 0;
|
||||
}
|
||||
|
||||
increment() {
|
||||
this.toggleCount++;
|
||||
}
|
||||
}
|
||||
|
||||
export function main() {
|
||||
commonDemoSetup();
|
||||
bootstrap(DemoApp, [
|
||||
bind(UrlResolver).toValue(new DemoUrlResolver())
|
||||
]);
|
||||
}
|
|
@ -61,6 +61,7 @@
|
|||
"fs-extra": "^0.16.4",
|
||||
"glob": "^4.0.6",
|
||||
"gulp": "^3.8.8",
|
||||
"gulp-autoprefixer": "^2.1.0",
|
||||
"gulp-changed": "^1.0.0",
|
||||
"gulp-clang-format": "^1.0.3",
|
||||
"gulp-concat": "^2.5.2",
|
||||
|
@ -68,6 +69,7 @@
|
|||
"gulp-jasmine": "^1.0.1",
|
||||
"gulp-load-plugins": "^0.7.1",
|
||||
"gulp-rename": "^1.2.0",
|
||||
"gulp-sass": "^1.3.3",
|
||||
"gulp-shell": "^0.2.10",
|
||||
"gulp-sourcemaps": "1.3.*",
|
||||
"gulp-template": "^3.0.0",
|
||||
|
|
|
@ -132,7 +132,7 @@ function getDocsTree() {
|
|||
var mdTree = stew.rename(modulesFunnel(['**/*.dart.md']),
|
||||
relativePath => relativePath.replace(/\.dart\.md$/, '.md'));
|
||||
// Copy all assets, ignore .js. and .dart. (handled above).
|
||||
var docs = modulesFunnel(['**/*.md', '**/*.png', '**/*.html', '**/*.css'],
|
||||
var docs = modulesFunnel(['**/*.md', '**/*.png', '**/*.html', '**/*.css', '**/*.scss'],
|
||||
['**/*.js.md', '**/*.dart.md']);
|
||||
return mergeTrees([licenses, mdTree, docs]);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue