diff --git a/demos/button.html b/demos/button.html index 5a7365880e6..432c91e95a8 100644 --- a/demos/button.html +++ b/demos/button.html @@ -26,22 +26,27 @@ @@ -69,339 +84,135 @@
- - + +
-
-
- Buttons - - - - - - - - - - -
- Div +
+
+
+ +
+ + + +
+
-
+ + +

Ripple Enabled

- Buttons CSS Only - - - - - - - - - - -
- Div + Text Button +
+ + + Link + + + + + +
- Links with Button Style - - Default - - - Raised - - - Dense Default - - - Dense Raised - - - Compact - - - Compact Raised - - - Default with Primary - - - Raised with Primary - - - Default with Secondary - - - Raised with Secondary - -
- -
- Disabled - - - - - - - - - - -
- Div + Raised Button +
+ + + Link + + + + + +
-
-
-
- Dark Theme (mdc-theme--dark) - Buttons - - - - - - - - - - -
- Div -
-
+

CSS Only

- Dark Theme (mdc-theme--dark) - Buttons CSS Only - - - - - - - - - - -
- Div -
-
-
- Dark Theme (mdc-theme--dark) - Disabled - - - - - - - - - - -
- Div + Text Button +
+ + + Link + + + + + +
-
-
- Dark Theme (mdc-button--theme-dark) - Buttons CSS Only - - - - - - - - - - -
- Div -
-
-
- Dark Theme (mdc-button--theme-dark) - Disabled - - - - - - - - - - -
- Div + Raised Button +
+ + + Link + + + + + +
@@ -427,6 +238,15 @@ mdc.ripple.MDCRipple.attachTo(btn); } } + + var demoWrapper = document.querySelector('.demo-wrapper'); + document.getElementById('toggle-dark').addEventListener('change', function () { + if (this.checked) { + demoWrapper.classList.add('mdc-theme--dark'); + } else { + demoWrapper.classList.remove('mdc-theme--dark'); + } + }); })(); diff --git a/packages/mdc-button/README.md b/packages/mdc-button/README.md index c1accde307d..101533204df 100644 --- a/packages/mdc-button/README.md +++ b/packages/mdc-button/README.md @@ -19,7 +19,8 @@ path: /catalog/buttons/ The MDC Button component is a spec-aligned button component adhering to the [Material Design button requirements](https://material.io/guidelines/components/buttons.html). It works without JavaScript with basic functionality for all states. -If you initiate the JavaScript object for a button, then it will be enhanced with ripple effects. (Not yet implemented) +You can enhance the button to have ripple effects by instantiating `MDCRipple` on +the `button` element. See [MDC Ripple](https://github.com/material-components/material-components-web/tree/master/packages/mdc-ripple) and [Demo](https://material-components-web.appspot.com/button.html) for details. ## Design & API Documentation @@ -40,23 +41,21 @@ npm install --save @material/button ## Usage -### Flat +### Button type -```html - -``` +> Note: Examples and documents use generic ` ``` -### Raised +#### Raised Button ```html ``` -### Disabled +### Button state + +#### Disabled + +Users can add `disabled` directly to the button element or set the fieldset containing +the button to `disabled` to disable a button. Disabled buttons cannot be interacted +with and have no visual interaction effect. ```html ``` +### Colored + +MDC Buttons have a default baseline color, but it is also possible to adopt the +application's primary or accent color by adding the `mdc-button--primary` or +`mdc-button--accent` modifier. + +```html + +``` + ### Adding ripples to buttons To add the ink ripple effect to a button, attach a [ripple](../mdc-ripple) instance to the diff --git a/packages/mdc-button/mdc-button.scss b/packages/mdc-button/mdc-button.scss index db860dcd98b..28aabce1459 100644 --- a/packages/mdc-button/mdc-button.scss +++ b/packages/mdc-button/mdc-button.scss @@ -17,65 +17,33 @@ @import "@material/elevation/mixins"; @import "@material/ripple/mixins"; @import "@material/theme/mixins"; +@import "@material/theme/variables"; @import "@material/typography/mixins"; // postcss-bem-linter: define button - .mdc-button { @include mdc-ripple-base; @include mdc-ripple-bg((pseudo: "::before")); @include mdc-ripple-fg((pseudo: "::after")); + @include mdc-typography(button); @include mdc-theme-prop(color, text-primary-on-light); - @include mdc-typography-base; display: inline-block; position: relative; - min-width: 64px; + min-width: 88px; height: 36px; padding: 0 16px; border: none; - border-radius: 2px; + border-radius: 4px; + box-sizing: border-box; outline: none; background: transparent; - font-size: 14px; - font-weight: 500; - letter-spacing: .04em; - line-height: 36px; text-align: center; - text-decoration: none; - text-transform: uppercase; overflow: hidden; vertical-align: middle; user-select: none; - box-sizing: border-box; -webkit-appearance: none; - &:not(.mdc-ripple-upgraded) { - -webkit-tap-highlight-color: rgba(black, .18); - } - - @include mdc-theme-dark { - @include mdc-ripple-base; - @include mdc-ripple-bg((pseudo: "::before", base-color: white, opacity: .14)); - @include mdc-ripple-fg((pseudo: "::after", base-color: white, opacity: .14)); - @include mdc-theme-prop(color, text-primary-on-dark); - - &:not(.mdc-ripple-upgraded) { - -webkit-tap-highlight-color: rgba(white, .18); - } - } - - @each $theme-style in (primary, secondary) { - // Needed for backward compatibility. Theme uses the term "secondary", but button still calls it "accent" for now. - $modifier: if($theme-style == "secondary", "accent", $theme-style); - - &.mdc-button--#{$modifier} { - @include mdc-ripple-base; - @include mdc-ripple-bg((pseudo: "::before", theme-style: $theme-style, opacity: .12)); - @include mdc-ripple-fg((pseudo: "::after", theme-style: $theme-style, opacity: .12)); - } - } - // postcss-bem-linter: ignore &:active { outline: none; @@ -90,113 +58,117 @@ border: 0; } - &--dense { - height: 32px; - font-size: .8125rem; // 13sp - line-height: 32px; + &:not(.mdc-ripple-upgraded) { + -webkit-tap-highlight-color: rgba(black, .3); } - // TODO(cristobalchao): Disable ink wash on hover and alter elevation instead for raised surfaces. - &--raised { - @include mdc-elevation(2); - @include mdc-elevation-transition; - - min-width: 88px; - - &:active { - @include mdc-elevation(8); - } - - @each $theme-style in (primary, secondary) { - // Needed for backward compatibility. Theme uses the term "secondary", but button still calls it "accent" for now. - $modifier: if($theme-style == "secondary", "accent", $theme-style); - - &.mdc-button--#{$modifier} { - @include mdc-ripple-base; - @include mdc-ripple-bg((pseudo: "::before", base-color: white, opacity: .14)); - @include mdc-ripple-fg((pseudo: "::after", base-color: white, opacity: .14)); - } - } + fieldset:disabled &, + &:disabled { + color: rgba(black, .38); + cursor: default; + pointer-events: none; @include mdc-theme-dark(".mdc-button") { - @include mdc-theme-prop(background-color, primary); - @include mdc-theme-prop(color, text-primary-on-primary); - - // postcss-bem-linter: ignore - &::before { - // We are explicitly not fully adhering to Material Design here. - // This should be the 700-shade when active instead of a black shade. - // Due to the complexity involved in adhering fully it is being ignored. - // Instead re-using the existing architecture for shading works just fine. - color: black; - } + @include mdc-theme-prop(color, text-disabled-on-dark); } } - &--primary { - @include mdc-theme-prop(color, primary); - - @include mdc-theme-dark(".mdc-button") { - @include mdc-theme-prop(color, primary); - } + @include mdc-theme-dark(".mdc-button") { + @include mdc-ripple-base; + @include mdc-ripple-bg((pseudo: "::before", base-color: white, opacity: .16)); + @include mdc-ripple-fg((pseudo: "::after", base-color: white, opacity: .16)); + @include mdc-theme-prop(color, text-primary-on-dark); - // postcss-bem-linter: ignore - &.mdc-button--raised { - @include mdc-theme-prop(background-color, primary); - @include mdc-theme-prop(color, text-primary-on-primary); - - // postcss-bem-linter: ignore - &::before { - color: black; - } + &:not(.mdc-ripple-upgraded) { + -webkit-tap-highlight-color: rgba(white, .18); } } +} - &--accent { - @include mdc-theme-prop(color, secondary); +.mdc-button--raised { + @include mdc-elevation(2); + @include mdc-elevation-transition; + @include mdc-ripple-base; + @include mdc-ripple-bg((pseudo: "::before", base-color: white, opacity: .32)); + @include mdc-ripple-fg((pseudo: "::after", base-color: white, opacity: .32)); + @include mdc-theme-prop(color, text-primary-on-dark); - @include mdc-theme-dark(".mdc-button") { - @include mdc-theme-prop(color, secondary); - } + background-color: black; - // postcss-bem-linter: ignore - &.mdc-button--raised { - @include mdc-theme-prop(background-color, secondary); - @include mdc-theme-prop(color, text-primary-on-secondary); - - // postcss-bem-linter: ignore - &::before { - color: black; - } - } + &:hover, + &:focus { + @include mdc-elevation(4); } - &--compact { - padding: 0 8px; + &:active { + @include mdc-elevation(8); } fieldset:disabled &, &:disabled { - color: rgba(0, 0, 0, .26); - cursor: default; - pointer-events: none; + @include mdc-elevation(0); + @include mdc-theme-prop(color, text-primary-on-dark); + + background-color: rgba(black, .15); @include mdc-theme-dark(".mdc-button") { - color: rgba(255, 255, 255, .3); + @include mdc-theme-prop(color, text-disabled-on-dark); + + background-color: rgba(255, 255, 255, .15); } } - fieldset:disabled &--raised, - &--raised:disabled { - @include mdc-elevation(0); + @include mdc-theme-dark(".mdc-button") { + @include mdc-ripple-base; + @include mdc-ripple-bg((pseudo: "::before", base-color: black, opacity: .32)); + @include mdc-ripple-fg((pseudo: "::after", base-color: black, opacity: .32)); + @include mdc-theme-prop(color, text-primary-on-light); - background-color: rgba(0, 0, 0, .12); - pointer-events: none; + background-color: white; - @include mdc-theme-dark(".mdc-button") { - background-color: rgba(255, 255, 255, .12); + &:not(.mdc-ripple-upgraded) { + -webkit-tap-highlight-color: rgba(black, .18); } } } +.mdc-button--compact { + padding: 0 8px; +} + +.mdc-button--dense { + height: 32px; + font-size: .8125rem; // 13sp + line-height: 32px; +} + +@each $theme-style in (primary, accent) { + // postcss-bem-linter: ignore + .mdc-button--#{$theme-style} { + $theme-value: map-get($mdc-theme-property-values, $theme-style); + + @include mdc-ripple-base; + @include mdc-ripple-bg((pseudo: "::before", base-color: $theme-value, opacity: .16)); + @include mdc-ripple-fg((pseudo: "::after", base-color: $theme-value, opacity: .16)); + @include mdc-theme-prop(color, $theme-style); + + @include mdc-theme-dark(".mdc-button") { + @include mdc-ripple-base; + @include mdc-ripple-bg((pseudo: "::before", base-color: $theme-value, opacity: .16)); + @include mdc-ripple-fg((pseudo: "::after", base-color: $theme-value, opacity: .16)); + @include mdc-theme-prop(color, $theme-style); + } + // postcss-bem-linter: ignore + &.mdc-button--raised, + &.mdc-button--unelevated { + $theme-value: map-get($mdc-theme-property-values, text-primary-on-#{$theme-style}); + + @include mdc-ripple-base; + @include mdc-ripple-bg((pseudo: "::before", base-color: $theme-value, opacity: .32)); + @include mdc-ripple-fg((pseudo: "::after", base-color: $theme-value, opacity: .32)); + @include mdc-theme-prop(background-color, $theme-style); + @include mdc-theme-prop(color, text-primary-on-#{$theme-style}); + } + } +} // postcss-bem-linter: end