mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat(button): add color attribute and unit tests
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
|
||||
@import "variables";
|
||||
@import "shadows";
|
||||
|
||||
// TODO(jelbourn): This goes away.
|
||||
@import "default-theme";
|
||||
@import "button-theme";
|
||||
|
||||
// Flat and raised button standards
|
||||
$md-button-padding: 0 16px !default;
|
||||
$md-button-min-width: 88px !default;
|
||||
$md-button-margin: 0 !default;
|
||||
$md-button-line-height: 36px !default;
|
||||
$md-button-border-radius: 3px !default;
|
||||
|
||||
// Fab standards
|
||||
$md-fab-border-radius: 50% !default;
|
||||
$md-fab-size: 56px !default;
|
||||
$md-fab-padding: 16px !default;
|
||||
|
||||
$md-mini-fab-size: 40px !default;
|
||||
$md-mini-fab-padding: 8px !default;
|
||||
|
||||
// Applies base styles to all button types.
|
||||
%md-button-base {
|
||||
@include md-button-theme('color');
|
||||
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
// Reset browser <button> styles.
|
||||
background: transparent;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
outline: none;
|
||||
border: none;
|
||||
|
||||
// Make anchors render like buttons.
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
text-decoration: none;
|
||||
vertical-align: middle;
|
||||
|
||||
// Typography.
|
||||
font-size: $md-body-font-size-base;
|
||||
font-family: $md-font-family;
|
||||
font-weight: 500;
|
||||
color: md-color($md-foreground, text);
|
||||
|
||||
// Sizing.
|
||||
margin: $md-button-margin;
|
||||
min-width: $md-button-min-width;
|
||||
line-height: $md-button-line-height;
|
||||
padding: $md-button-padding;
|
||||
border-radius: $md-button-border-radius;
|
||||
|
||||
&[disabled] {
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
// Applies styles to buttons with backgrounds: raised, fab, and mini-fab
|
||||
%md-raised-button {
|
||||
@extend %md-button-base;
|
||||
|
||||
@include md-button-theme('color', default-contrast);
|
||||
@include md-button-theme('background-color');
|
||||
|
||||
background-color: md-color($md-background, background);
|
||||
box-shadow: $md-shadow-bottom-z-1;
|
||||
// Force hardware acceleration.
|
||||
transform: translate3d(0, 0, 0);
|
||||
|
||||
// Animation.
|
||||
transition: background $swift-ease-out-duration $swift-ease-out-timing-function,
|
||||
box-shadow $swift-ease-out-duration $swift-ease-out-timing-function;
|
||||
|
||||
&:active {
|
||||
box-shadow: $md-shadow-bottom-z-2;
|
||||
}
|
||||
|
||||
&.md-button-focus {
|
||||
background-color: md-color($md-foreground, base, 0.12);
|
||||
@include md-button-theme('background-color', 600);
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Applies styles to fab and mini-fab button types only
|
||||
@mixin md-fab($size, $padding) {
|
||||
@extend %md-raised-button;
|
||||
|
||||
min-width: 0;
|
||||
border-radius: $md-fab-border-radius;
|
||||
background-color: md-color($md-accent);
|
||||
width: $size;
|
||||
height: $size;
|
||||
padding: $padding;
|
||||
|
||||
&.md-button-focus {
|
||||
background-color: md-color($md-accent, 600);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
// Applies specified coloring to three supported palettes
|
||||
@mixin md-button-theme ($property, $color:500, $opacity: 1) {
|
||||
&.md-primary {
|
||||
#{$property}: md-color($md-primary, $color, $opacity);
|
||||
}
|
||||
&.md-accent {
|
||||
#{$property}: md-color($md-accent, $color, $opacity);
|
||||
}
|
||||
&.md-warn {
|
||||
#{$property}: md-color($md-warn, $color, $opacity);
|
||||
}
|
||||
|
||||
&.md-primary, &.md-accent, &.md-warn, &[disabled] {
|
||||
&[disabled] {
|
||||
$palette: if($property == 'color', $md-foreground, $md-background);
|
||||
#{$property}: md-color($palette, disabled-button);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,195 +1,39 @@
|
||||
@import "variables";
|
||||
@import "shadows";
|
||||
|
||||
// TODO(jelbourn): This goes away.
|
||||
@import "default-theme";
|
||||
|
||||
// TODO(jelbourn): Move variables and mixins into a partial file.
|
||||
// TODO(jelbourn): Measure perf benefits for translate3d and will-change.
|
||||
// TODO(jelbourn): Figure out if anchor hover underline actually happens in any browser.
|
||||
|
||||
@import "button-base";
|
||||
|
||||
// Standard button sizing.
|
||||
$md-button-padding: 0 rem(0.600) !default;
|
||||
$md-button-min-width: rem(8.800) !default;
|
||||
$md-button-margin: rem(0.600) rem(0.800) !default;
|
||||
$md-button-line-height: rem(3.60) !default;
|
||||
$md-button-border-radius: 3px !default;
|
||||
|
||||
// FAB sizing.
|
||||
$md-fab-size: rem(5.600) !default;
|
||||
$md-fab-line-height: rem(5.600) !default;
|
||||
$md-fab-padding: rem(1.60) !default;
|
||||
$md-fab-mini-size: rem(4.00) !default;
|
||||
$md-fab-mini-line-height: rem(4.00) !default;
|
||||
|
||||
/** Mixin to create distinct classes for fab positions, e.g. ".md-fab-position-bottom-right". */
|
||||
@mixin md-fab-position($spot, $top: auto, $right: auto, $bottom: auto, $left: auto) {
|
||||
.md-fab-position-#{$spot} {
|
||||
top: $top;
|
||||
right: $right;
|
||||
bottom: $bottom;
|
||||
left: $left;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
/** Styles for all disabled buttons. */
|
||||
@mixin md-button-disabled() {
|
||||
color: md-color($md-foreground, disabled);
|
||||
background-color: transparent;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/** Base styles for all buttons. */
|
||||
@mixin md-button-base() {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
// Reset browser <button> styles.
|
||||
background: transparent;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
outline: none;
|
||||
border: none;
|
||||
|
||||
// Make anchors render like buttons.
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
text-decoration: none;
|
||||
vertical-align: middle;
|
||||
|
||||
// Typography.
|
||||
font-size: $md-body-font-size-base;
|
||||
font-weight: 500;
|
||||
|
||||
// Sizing.
|
||||
padding: $md-button-padding;
|
||||
margin: $md-button-margin;
|
||||
min-width: $md-button-min-width;
|
||||
line-height: $md-button-line-height;
|
||||
border-radius: $md-button-border-radius;
|
||||
|
||||
// Animation.
|
||||
transition: background $swift-ease-out-duration $swift-ease-out-timing-function,
|
||||
box-shadow $swift-ease-out-duration $swift-ease-out-timing-function;
|
||||
|
||||
// Hide the browser focus indicator, instead applying our own focus style on background-color.
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:hover, &:focus {
|
||||
// Remove anchor underline again for more specific modifiers.
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
// Use a CSS class for focus style because we only want to render the focus style when
|
||||
// the focus originated from a keyboard event (see JS source for more details).
|
||||
&:hover, &.md-button-focus {
|
||||
background: md-color($md-background, background, 0.2);
|
||||
}
|
||||
|
||||
&.md-primary {
|
||||
color: md-color($md-primary);
|
||||
}
|
||||
|
||||
&.md-accent {
|
||||
color: md-color($md-accent);
|
||||
}
|
||||
|
||||
// Use the [disabled] attribute instead of the :disabled pseudo-class because anchors
|
||||
// cannot technically be :disabled.
|
||||
&[disabled] {
|
||||
@include md-button-disabled();
|
||||
}
|
||||
}
|
||||
|
||||
/** Base styles for raised buttons, including FABs. */
|
||||
@mixin md-raised-button() {
|
||||
@include md-button-base();
|
||||
|
||||
// Force hardware acceleration.
|
||||
transform: translate3d(0, 0, 0);
|
||||
|
||||
box-shadow: $md-shadow-bottom-z-1;
|
||||
|
||||
&:active {
|
||||
box-shadow: $md-shadow-bottom-z-2;
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&.md-primary {
|
||||
color: md-color($md-primary, default-contrast);
|
||||
background-color: md-color($md-primary);
|
||||
|
||||
&:hover, &.md-button-focus {
|
||||
background-color: md-color($md-primary, 600);
|
||||
}
|
||||
}
|
||||
|
||||
&.md-accent {
|
||||
color: md-color($md-accent, default-contrast);
|
||||
background-color: md-color($md-accent);
|
||||
|
||||
&:hover, &.md-button-focus {
|
||||
background-color: md-color($md-accent, A700);
|
||||
}
|
||||
}
|
||||
|
||||
&.md-primary, &.md-accent {
|
||||
&[disabled] {
|
||||
@include md-button-disabled();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO(kara): Replace attribute selectors with class selectors when possible
|
||||
[md-button] {
|
||||
@include md-button-base();
|
||||
@extend %md-button-base;
|
||||
|
||||
&:hover, &.md-button-focus {
|
||||
background-color: md-color($md-foreground, base, 0.12);
|
||||
@include md-button-theme('background-color', 0.12);
|
||||
}
|
||||
|
||||
&[disabled]:hover {
|
||||
&.md-primary, &.md-accent, &.md-warn, &:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[md-raised-button] {
|
||||
@include md-raised-button();
|
||||
|
||||
color: md-color($md-foreground, text);
|
||||
background-color: md-color($md-background, background);
|
||||
@extend %md-raised-button;
|
||||
}
|
||||
|
||||
[md-fab] {
|
||||
@include md-raised-button();
|
||||
|
||||
z-index: $z-index-fab;
|
||||
|
||||
border-radius: 50%;
|
||||
min-width: 0;
|
||||
width: $md-fab-size;
|
||||
height: $md-fab-size;
|
||||
line-height: $md-fab-line-height;
|
||||
vertical-align: middle;
|
||||
|
||||
&.md-mini {
|
||||
line-height: $md-fab-mini-line-height;
|
||||
width: $md-fab-mini-size;
|
||||
height: $md-fab-mini-size;
|
||||
}
|
||||
@include md-fab($md-fab-size, $md-fab-padding);
|
||||
}
|
||||
|
||||
// Styles for high contrast mode.
|
||||
[md-mini-fab] {
|
||||
@include md-fab($md-mini-fab-size, $md-mini-fab-padding)
|
||||
}
|
||||
|
||||
// Applies a clearer border for high-contrast mode (a11y)
|
||||
@media screen and (-ms-high-contrast: active) {
|
||||
[md-raised],
|
||||
[md-fab] {
|
||||
.md-raised-button, .md-fab, .md-mini-fab {
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
}
|
||||
|
||||
$md-fab-pos-offset: ($md-fab-size - $md-fab-padding) / 2;
|
||||
@include md-fab-position(bottom-right, auto, $md-fab-pos-offset, $md-fab-pos-offset, auto);
|
||||
@include md-fab-position(bottom-left, auto, auto, $md-fab-pos-offset, $md-fab-pos-offset);
|
||||
@include md-fab-position(top-right, $md-fab-pos-offset, $md-fab-pos-offset, auto, auto);
|
||||
@include md-fab-position(top-left, $md-fab-pos-offset, auto, auto, $md-fab-pos-offset);
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
import {provide, Component, DebugElement} from 'angular2/core';
|
||||
import {By} from 'angular2/platform/browser';
|
||||
|
||||
import {MdButton} from './button';
|
||||
import {MdButton, MdAnchor} from './button';
|
||||
import {AsyncTestFn, FunctionWithParamTokens} from 'angular2/testing';
|
||||
|
||||
export function main() {
|
||||
@@ -24,6 +24,27 @@ export function main() {
|
||||
builder = tcb;
|
||||
}));
|
||||
|
||||
// General button tests
|
||||
it('should apply class based on color attribute', (done:() => void) => {
|
||||
return builder.createAsync(TestApp).then((fixture) => {
|
||||
let testComponent = fixture.debugElement.componentInstance;
|
||||
let buttonDebugElement = fixture.debugElement.query(By.css('button'));
|
||||
let aDebugElement = fixture.debugElement.query(By.css('a'));
|
||||
|
||||
testComponent.buttonColor = 'primary';
|
||||
fixture.detectChanges();
|
||||
expect(buttonDebugElement.nativeElement.classList.contains('md-primary')).toBe(true);
|
||||
expect(aDebugElement.nativeElement.classList.contains('md-primary')).toBe(true);
|
||||
|
||||
testComponent.buttonColor = 'accent';
|
||||
fixture.detectChanges();
|
||||
expect(buttonDebugElement.nativeElement.classList.contains('md-accent')).toBe(true);
|
||||
expect(aDebugElement.nativeElement.classList.contains('md-accent')).toBe(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
// Regular button tests
|
||||
describe('button[md-button]', () => {
|
||||
it('should handle a click on the button', (done:() => void) => {
|
||||
return builder.createAsync(TestApp).then((fixture) => {
|
||||
@@ -48,7 +69,52 @@ export function main() {
|
||||
|
||||
expect(testComponent.clickCount).toBe(0);
|
||||
done();
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// Anchor button tests
|
||||
describe('a[md-button]', () => {
|
||||
it('should not redirect if disabled',(done:() => void)=>{
|
||||
return builder.createAsync(TestApp).then((fixture) => {
|
||||
let testComponent = fixture.debugElement.componentInstance;
|
||||
let buttonDebugElement = fixture.debugElement.query(By.css('a'));
|
||||
|
||||
testComponent.isDisabled = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
buttonDebugElement.nativeElement.click();
|
||||
// will error if page reloads
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should remove tabindex if disabled', (done:() => void) => {
|
||||
return builder.createAsync(TestApp).then((fixture) => {
|
||||
let testComponent = fixture.debugElement.componentInstance;
|
||||
let buttonDebugElement = fixture.debugElement.query(By.css('a'));
|
||||
expect(buttonDebugElement.nativeElement.getAttribute('tabIndex')).toBe(null);
|
||||
|
||||
testComponent.isDisabled = true;
|
||||
fixture.detectChanges();
|
||||
expect(buttonDebugElement.nativeElement.getAttribute('tabIndex')).toBe('-1');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should add aria-disabled attribute if disabled', (done:() => void) => {
|
||||
return builder.createAsync(TestApp).then((fixture) => {
|
||||
let testComponent = fixture.debugElement.componentInstance;
|
||||
let buttonDebugElement = fixture.debugElement.query(By.css('a'));
|
||||
fixture.detectChanges();
|
||||
expect(buttonDebugElement.nativeElement.getAttribute('aria-disabled')).toBe('false');
|
||||
|
||||
testComponent.isDisabled = true;
|
||||
fixture.detectChanges();
|
||||
expect(buttonDebugElement.nativeElement.getAttribute('aria-disabled')).toBe('true');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -63,9 +129,13 @@ function testAsync(fn: Function): FunctionWithParamTokens {
|
||||
/** Test component that contains an MdButton. */
|
||||
@Component({
|
||||
selector: 'test-app',
|
||||
directives: [MdButton],
|
||||
template:
|
||||
`<button md-button type="button" (click)="increment()" [disabled]="isDisabled">Go</button>`,
|
||||
template: `
|
||||
<button md-button type="button" (click)="increment()" [disabled]="isDisabled" [color]="buttonColor">
|
||||
Go
|
||||
</button>
|
||||
<a href="http://www.google.com" md-button [disabled]="isDisabled" [color]="buttonColor">Link</a>
|
||||
`,
|
||||
directives: [MdButton, MdAnchor]
|
||||
})
|
||||
class TestApp {
|
||||
clickCount: number = 0;
|
||||
@@ -75,3 +145,5 @@ class TestApp {
|
||||
this.clickCount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,29 +1,36 @@
|
||||
import {Component, View, ViewEncapsulation, OnChanges, SimpleChange} from 'angular2/core';
|
||||
|
||||
import {Component, View, ViewEncapsulation, Input, Attribute, HostBinding, HostListener} from 'angular2/core';
|
||||
|
||||
// TODO(jelbourn): Ink ripples.
|
||||
// TODO(jelbourn): Make the `isMouseDown` stuff done with one global listener.
|
||||
// TODO(kara): Convert attribute selectors to classes when attr maps become available
|
||||
|
||||
|
||||
@Component({
|
||||
selector: '[md-button]:not(a), [md-raised-button]:not(a), [md-fab]:not(a)',
|
||||
selector: '[md-button]:not(a), [md-raised-button]:not(a), [md-fab]:not(a), [md-mini-fab]:not(a)',
|
||||
inputs: ['color'],
|
||||
host: {
|
||||
'(mousedown)': 'onMousedown()',
|
||||
'(focus)': 'onFocus()',
|
||||
'(blur)': 'onBlur()',
|
||||
'[class.md-button-focus]': 'isKeyboardFocused',
|
||||
'[class]': 'setClassList()',
|
||||
'(mousedown)': 'setMousedown()',
|
||||
'(focus)': 'setKeyboardFocus()',
|
||||
'(blur)': 'removeKeyboardFocus()'
|
||||
},
|
||||
templateUrl: './components/button/button.html',
|
||||
styleUrls: ['./components/button/button.css'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class MdButton {
|
||||
/** Whether a mousedown has occured on this element in the last 100ms. */
|
||||
isMouseDown: boolean = false;
|
||||
color: string;
|
||||
|
||||
/** Whether the button has focus from the keyboard (not the mouse). Used for class binding. */
|
||||
isKeyboardFocused: boolean = false;
|
||||
|
||||
onMousedown() {
|
||||
/** Whether a mousedown has occurred on this element in the last 100ms. */
|
||||
isMouseDown: boolean = false;
|
||||
|
||||
setClassList() {return `md-${this.color}`;}
|
||||
|
||||
setMousedown() {
|
||||
// We only *show* the focus style when focus has come to the button via the keyboard.
|
||||
// The Material Design spec is silent on this topic, and without doing this, the
|
||||
// button continues to look :active after clicking.
|
||||
@@ -32,61 +39,58 @@ export class MdButton {
|
||||
setTimeout(() => { this.isMouseDown = false; }, 100);
|
||||
}
|
||||
|
||||
onFocus() {
|
||||
setKeyboardFocus($event: any) {
|
||||
this.isKeyboardFocused = !this.isMouseDown;
|
||||
}
|
||||
|
||||
onBlur() {
|
||||
removeKeyboardFocus() {
|
||||
this.isKeyboardFocused = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'a[md-button], a[md-raised-button], a[md-fab]',
|
||||
inputs: ['disabled'],
|
||||
selector: 'a[md-button], a[md-raised-button], a[md-fab], a[md-mini-fab]',
|
||||
inputs: ['color'],
|
||||
host: {
|
||||
'(click)': 'onClick($event)',
|
||||
'(mousedown)': 'onMousedown()',
|
||||
'(focus)': 'onFocus()',
|
||||
'(blur)': 'onBlur()',
|
||||
'[tabIndex]': 'tabIndex',
|
||||
'[class.md-button-focus]': 'isKeyboardFocused',
|
||||
'[attr.aria-disabled]': 'isAriaDisabled',
|
||||
'[class]': 'setClassList()',
|
||||
'(mousedown)': 'setMousedown()',
|
||||
'(focus)': 'setKeyboardFocus()',
|
||||
'(blur)': 'removeKeyboardFocus()'
|
||||
},
|
||||
templateUrl: './components/button/button.html',
|
||||
styleUrls: ['./components/button/button.css'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class MdAnchor extends MdButton implements OnChanges {
|
||||
tabIndex: number;
|
||||
disabled_: boolean;
|
||||
export class MdAnchor extends MdButton {
|
||||
disabled_: boolean = null;
|
||||
|
||||
get disabled(): boolean {
|
||||
return this.disabled_;
|
||||
}
|
||||
|
||||
set disabled(value) {
|
||||
// The presence of *any* disabled value makes the component disabled, *except* for false.
|
||||
this.disabled_ = value != null && this.disabled !== false;
|
||||
}
|
||||
|
||||
onClick(event: Event) {
|
||||
// A disabled anchor shouldn't navigate anywhere.
|
||||
if (this.disabled) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
/** Invoked when a change is detected. */
|
||||
ngOnChanges(changes: {[propName: string]: SimpleChange}) {
|
||||
// A disabled anchor should not be in the tab flow.
|
||||
this.tabIndex = this.disabled ? -1 : 0;
|
||||
@HostBinding('tabIndex')
|
||||
get tabIndex():number {
|
||||
return this.disabled ? -1 : 0;
|
||||
}
|
||||
|
||||
@HostBinding('attr.aria-disabled')
|
||||
/** Gets the aria-disabled value for the component, which must be a string for Dart. */
|
||||
get isAriaDisabled(): string {
|
||||
return this.disabled ? 'true' : 'false';
|
||||
}
|
||||
}
|
||||
|
||||
@HostBinding('attr.disabled')
|
||||
@Input('disabled')
|
||||
get disabled() { return this.disabled_; }
|
||||
|
||||
set disabled(value: boolean) {
|
||||
// The presence of *any* disabled value makes the component disabled, *except* for false.
|
||||
this.disabled_ = (value != null && value != false) ? true : null;
|
||||
}
|
||||
|
||||
@HostListener('click', ['$event'])
|
||||
haltDisabledEvents(event: Event) {
|
||||
// A disabled button shouldn't apply any actions
|
||||
if (this.disabled) {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ md-card {
|
||||
padding: $md-card-default-padding;
|
||||
border-radius: $md-card-border-radius;
|
||||
box-shadow: $md-shadow-bottom-z-1;
|
||||
font-family: $font-family;
|
||||
font-family: $md-font-family;
|
||||
background: md-color($md-background, card);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,6 @@ $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-warn: md-palette($md-red, 500, 300, 800, $md-contrast-palettes);
|
||||
$md-warn: md-palette($md-orange, 500, 300, 800, $md-contrast-palettes);
|
||||
$md-foreground: if($md-is-dark-theme, $md-dark-theme-foreground, $md-light-theme-foreground);
|
||||
$md-background: if($md-is-dark-theme, $md-dark-theme-background, $md-light-theme-background);
|
||||
|
||||
@@ -334,6 +334,7 @@ $md-light-theme-background: (
|
||||
background: map_get($md-grey, 50),
|
||||
card: white,
|
||||
dialog: white,
|
||||
disabled-button: rgba(black, 0.12)
|
||||
);
|
||||
|
||||
// Background palette for dark themes.
|
||||
@@ -343,34 +344,37 @@ $md-dark-theme-background: (
|
||||
background: #303030,
|
||||
card: map_get($md-grey, 800),
|
||||
dialog: map_get($md-grey, 800),
|
||||
disabled-button: rgba(white, 0.12)
|
||||
);
|
||||
|
||||
// Foreground palette for light themes.
|
||||
$md-light-theme-foreground: (
|
||||
base: black,
|
||||
divider: rgba(black, 0.12),
|
||||
dividers: rgba(black, 0.12),
|
||||
disabled: rgba(black, 0.38),
|
||||
disabled-text: rgba(black, 0.38),
|
||||
hint-text: rgba(black, 0.38),
|
||||
secondary-text: rgba(black, 0.54),
|
||||
icon: rgba(black, 0.54),
|
||||
icons: rgba(black, 0.54),
|
||||
text: rgba(black, 0.87)
|
||||
base: black,
|
||||
divider: rgba(black, 0.12),
|
||||
dividers: rgba(black, 0.12),
|
||||
disabled: rgba(black, 0.38),
|
||||
disabled-button: rgba(black, 0.38),
|
||||
disabled-text: rgba(black, 0.38),
|
||||
hint-text: rgba(black, 0.38),
|
||||
secondary-text: rgba(black, 0.54),
|
||||
icon: rgba(black, 0.54),
|
||||
icons: rgba(black, 0.54),
|
||||
text: rgba(black, 0.87)
|
||||
);
|
||||
|
||||
// Foreground palette for dark themes.
|
||||
$md-dark-theme-foreground: (
|
||||
base: white,
|
||||
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
|
||||
base: white,
|
||||
divider: rgba(white, 0.12),
|
||||
dividers: rgba(white, 0.12),
|
||||
disabled: rgba(white, 0.30),
|
||||
disabled-button: 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
|
||||
);
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
// Typography
|
||||
$md-body-font-size-base: rem(1.400) !default;
|
||||
$font-family: Roboto, 'Helvetica Neue', sans-serif !default;
|
||||
$md-font-family: Roboto, 'Helvetica Neue', sans-serif !default;
|
||||
|
||||
// Media queries
|
||||
$md-xsmall: "max-width: 600px";
|
||||
|
||||
@@ -1,3 +1,60 @@
|
||||
<button md-button>HELLO</button>
|
||||
<button md-raised-button class="md-primary">HELLO</button>
|
||||
<button md-fab class="md-accent">HI</button>
|
||||
<section>
|
||||
<button md-button>flat</button>
|
||||
<button md-raised-button>raised</button>
|
||||
<button md-fab>
|
||||
<i class="material-icons md-24">check circle</i>
|
||||
</button>
|
||||
<button md-mini-fab>
|
||||
<i class="material-icons md-24">check circle</i>
|
||||
</button>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<a href="http://www.google.com" md-button color="primary">link</a>
|
||||
<a href="http://www.google.com" md-raised-button>link</a>
|
||||
<a href="http://www.google.com" md-fab>
|
||||
<i class="material-icons md-24">check circle</i>
|
||||
</a>
|
||||
<a href="http://www.google.com" md-mini-fab>
|
||||
<i class="material-icons md-24">check circle</i>
|
||||
</a>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<button md-button color="primary">primary</button>
|
||||
<button md-button color="accent">accent</button>
|
||||
<button md-button color="warn">warn</button>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<button md-raised-button color="primary">primary</button>
|
||||
<button md-raised-button color="accent">accent</button>
|
||||
<button md-raised-button color="warn">warn</button>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<button md-fab color="primary">
|
||||
<i class="material-icons md-24">home</i>
|
||||
</button>
|
||||
<button md-fab color="accent">
|
||||
<i class="material-icons md-24">favorite</i>
|
||||
</button>
|
||||
<button md-fab color="warn">
|
||||
<i class="material-icons md-24">feedback</i>
|
||||
</button>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div>
|
||||
<span>isDisabled: {{isDisabled}}</span>
|
||||
<button md-raised-button (click)="isDisabled=!isDisabled">Disable buttons</button>
|
||||
</div>
|
||||
<button md-button [disabled]="isDisabled">off</button>
|
||||
<button md-button color="primary" [disabled]="isDisabled">off</button>
|
||||
<a href="http://www.google.com" md-button color="accent" [disabled]="isDisabled">off</a>
|
||||
<button md-raised-button color="primary" [disabled]="isDisabled">off</button>
|
||||
<button md-mini-fab [disabled]="isDisabled">
|
||||
<i class="material-icons md-24">check circle</i>
|
||||
</button>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
// Helps fonts on OSX looks more consistent with other systems
|
||||
// Isn't currently in button styles due to performance concerns
|
||||
* {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
button, a, {
|
||||
margin: 8px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
|
||||
section {
|
||||
background-color: #f7f7f7;
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import {Component} from 'angular2/core';
|
||||
import {MdButton} from '../../components/button/button';
|
||||
import {MdButton, MdAnchor} from '../../components/button/button';
|
||||
|
||||
@Component({
|
||||
selector: 'button-demo',
|
||||
templateUrl: 'demo-app/button/button-demo.html',
|
||||
styleUrls: ['demo-app/button/button-demo.css'],
|
||||
directives: [MdButton]
|
||||
directives: [MdButton, MdAnchor]
|
||||
})
|
||||
export class ButtonDemo {}
|
||||
export class ButtonDemo {
|
||||
isDisabled: boolean = false;
|
||||
|
||||
}
|
||||
@@ -7,6 +7,8 @@
|
||||
<script src="vendor/angular2/bundles/angular2-polyfills.js"></script>
|
||||
{{content-for 'head'}}
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
|
||||
rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<demo-app>Loading...</demo-app>
|
||||
|
||||
Reference in New Issue
Block a user