diff --git a/src/components/button/_button-base.scss b/src/components/button/_button-base.scss new file mode 100644 index 00000000000..1e41ae881af --- /dev/null +++ b/src/components/button/_button-base.scss @@ -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 `, + template: ` + + Link + `, + directives: [MdButton, MdAnchor] }) class TestApp { clickCount: number = 0; @@ -75,3 +145,5 @@ class TestApp { this.clickCount++; } } + + diff --git a/src/components/button/button.ts b/src/components/button/button.ts index 963b8a42d4c..9964fd63ace 100644 --- a/src/components/button/button.ts +++ b/src/components/button/button.ts @@ -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(); + } + } +} \ No newline at end of file diff --git a/src/components/card/card.scss b/src/components/card/card.scss index 56c66df33c6..9ec0e922ee9 100644 --- a/src/components/card/card.scss +++ b/src/components/card/card.scss @@ -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); } diff --git a/src/core/style/_default-theme.scss b/src/core/style/_default-theme.scss index a99ee6c19b8..198589e37f1 100644 --- a/src/core/style/_default-theme.scss +++ b/src/core/style/_default-theme.scss @@ -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); diff --git a/src/core/style/_palette.scss b/src/core/style/_palette.scss index ed0aff502a6..1b0434efd64 100644 --- a/src/core/style/_palette.scss +++ b/src/core/style/_palette.scss @@ -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 ); diff --git a/src/core/style/_variables.scss b/src/core/style/_variables.scss index 70f1400d2f2..b4a50ae55f1 100644 --- a/src/core/style/_variables.scss +++ b/src/core/style/_variables.scss @@ -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"; diff --git a/src/demo-app/button/button-demo.html b/src/demo-app/button/button-demo.html index 976f4b02423..befde24849f 100644 --- a/src/demo-app/button/button-demo.html +++ b/src/demo-app/button/button-demo.html @@ -1,3 +1,60 @@ - - - \ No newline at end of file +
+ + + + +
+ +
+ link + link + + check circle + + + check circle + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+
+ isDisabled: {{isDisabled}} + +
+ + + off + + +
+ diff --git a/src/demo-app/button/button-demo.scss b/src/demo-app/button/button-demo.scss index e69de29bb2d..8e87fbfdefe 100644 --- a/src/demo-app/button/button-demo.scss +++ b/src/demo-app/button/button-demo.scss @@ -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; +} + diff --git a/src/demo-app/button/button-demo.ts b/src/demo-app/button/button-demo.ts index 80c3fad206c..4d12c44f775 100644 --- a/src/demo-app/button/button-demo.ts +++ b/src/demo-app/button/button-demo.ts @@ -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 {} \ No newline at end of file +export class ButtonDemo { + isDisabled: boolean = false; + +} \ No newline at end of file diff --git a/src/index.html b/src/index.html index 0969e3d7af1..680b352267d 100644 --- a/src/index.html +++ b/src/index.html @@ -7,6 +7,8 @@ {{content-for 'head'}} + Loading...