feat(button) localize focus management and styles (#13690)

* feat(button) handle button focus locally

* chore() remove global focus styles

* feat(button) add button md focus styles

* feat(button) add ios focus styles

* fix(button) adjust ios clear focus styles
This commit is contained in:
Cam Wiegert
2017-12-21 16:00:22 -06:00
committed by GitHub
parent 00e11bd4d9
commit 14f7b4977f
8 changed files with 160 additions and 31 deletions

View File

@@ -25,6 +25,10 @@
opacity: $button-ios-opacity-activated;
}
.button-ios.focused {
background-color: $button-ios-background-color-focused;
}
.button-ios:hover:not(.disable-hover) {
opacity: $button-ios-opacity-hover;
}
@@ -40,6 +44,7 @@
@mixin ios-button-default($color-name, $color-base, $color-contrast) {
$bg-color: $color-base;
$bg-color-activated: color-shade($bg-color);
$bg-color-focused: color-shade($color-base, 12%);
$fg-color: $color-contrast;
.button-ios-#{$color-name} {
@@ -50,6 +55,10 @@
.button-ios-#{$color-name}.activated {
background-color: $bg-color-activated;
}
.button-ios-#{$color-name}.focused {
background-color: $bg-color-focused;
}
}
@@ -109,10 +118,20 @@
opacity: $button-ios-outline-opacity-activated;
}
.button-outline-ios.focused {
background-color: $button-ios-outline-background-color-focused;
}
.button-outline-ios.activated.focused {
background-color: color-shade($button-ios-background-color, 12%);
border-color: color-shade($button-ios-background-color, 12%);
}
// iOS Outline Button Color Mixin
// --------------------------------------------------
@mixin ios-button-outline($color-name, $color-base, $color-contrast) {
$bg-color-focused: rgba($color-base, 0.12);
.button-outline-ios-#{$color-name} {
border-color: $color-base;
@@ -125,6 +144,14 @@
background-color: $color-base;
}
.button-outline-ios-#{$color-name}.focused {
background-color: $bg-color-focused;
}
.button-outline-ios-#{$color-name}.activated.focused {
background-color: color-shade($color-base, 12%);
border-color: color-shade($color-base, 12%);
}
}
@@ -142,6 +169,10 @@
opacity: $button-ios-clear-opacity-activated;
}
.button-clear-ios.focused {
background-color: $button-ios-clear-background-color-focused;
}
.button-clear-ios:hover:not(.disable-hover) {
color: $button-ios-clear-text-color-hover;
opacity: $button-ios-clear-opacity-hover;
@@ -153,6 +184,7 @@
@mixin ios-button-clear($color-name, $color-base, $color-contrast) {
$fg-color: $color-base;
$bg-color-focused: rgba($color-base, 0.12);
.button-clear-ios-#{$color-name} {
border-color: $button-ios-clear-border-color;
@@ -164,6 +196,10 @@
opacity: $button-ios-clear-opacity-activated;
}
.button-clear-ios-#{$color-name}.focused {
background-color: $bg-color-focused;
}
.button-clear-ios-#{$color-name}:hover:not(.disable-hover) {
color: $fg-color;
}

View File

@@ -54,6 +54,9 @@ $button-ios-opacity-activated: 1 !default;
/// @prop - Opacity of the button on hover
$button-ios-opacity-hover: .8 !default;
/// @prop - Background color of the focused button
$button-ios-background-color-focused: color-shade($button-ios-background-color, 12%) !default;
// iOS Large Button
// --------------------------------------------------
@@ -129,6 +132,9 @@ $button-ios-outline-background-color-activated: $button-ios-background-color
/// @prop - Opacity of the activated outline button
$button-ios-outline-opacity-activated: 1 !default;
/// @prop - Background color of the focused outline button
$button-ios-outline-background-color-focused: rgba($button-ios-background-color, 0.12) !default;
// iOS Clear Button
// --------------------------------------------------
@@ -151,6 +157,9 @@ $button-ios-clear-text-color-hover: $button-ios-background-color
/// @prop - Opacity of the clear button on hover
$button-ios-clear-opacity-hover: .6 !default;
/// @prop - Background color of the focused clear button
$button-ios-clear-background-color-focused: rgba($button-ios-background-color, 0.12) !default;
// iOS Round Button
// --------------------------------------------------

View File

@@ -37,6 +37,10 @@
box-shadow: $button-md-box-shadow-activated;
}
.button-md.focused {
background-color: $button-md-background-color-focused;
}
.button-md .button-effect {
background-color: $button-md-text-color;
}
@@ -52,6 +56,7 @@
@mixin md-button-default($color-name, $color-base, $color-contrast) {
$bg-color: $color-base;
$bg-color-activated: color-shade($bg-color);
$bg-color-focused: color-shade($bg-color, 12%);
$fg-color: $color-contrast;
.button-md-#{$color-name} {
@@ -68,6 +73,10 @@
opacity: $button-md-opacity-activated;
}
.button-md-#{$color-name}.focused {
background-color: $bg-color-focused;
}
.button-md-#{$color-name} .button-effect {
background-color: $fg-color;
}
@@ -133,6 +142,10 @@
opacity: $button-md-outline-opacity-activated;
}
.button-outline-md.focused {
background-color: $button-md-outline-background-color-focused;
}
.button-outline-md .button-effect {
background-color: $button-md-outline-ripple-background-color;
}
@@ -143,6 +156,7 @@
@mixin md-button-outline($color-name, $color-base, $color-contrast) {
$fg-color: color-shade($color-base, 5%);
$bg-color-focused: rgba($color-base, 0.12);
.button-outline-md-#{$color-name} {
border-color: $fg-color;
@@ -158,6 +172,10 @@
background-color: $button-md-outline-background-color-activated;
}
.button-outline-md-#{$color-name}.focused {
background-color: $bg-color-focused;
}
.button-outline-md-#{$color-name} .button-effect {
background-color: $fg-color;
}
@@ -180,6 +198,10 @@
box-shadow: $button-md-clear-box-shadow-activated;
}
.button-clear-md.focused {
background-color: $button-md-clear-background-color-focused;
}
.button-clear-md:hover:not(.disable-hover) {
background-color: $button-md-clear-background-color-hover;
}
@@ -194,6 +216,7 @@
@mixin md-button-clear($color-name, $color-base, $color-contrast) {
$fg-color: $color-base;
$bg-color-focused: rgba($color-base, 0.12);
.button-clear-md-#{$color-name} {
border-color: $button-md-clear-border-color;
@@ -206,6 +229,10 @@
box-shadow: $button-md-clear-box-shadow-activated;
}
.button-clear-md-#{$color-name}.focused {
background-color: $bg-color-focused;
}
.button-clear-md-#{$color-name}:hover:not(.disable-hover) {
color: $fg-color;
}

View File

@@ -75,6 +75,9 @@ $button-md-box-shadow-activated: 0 3px 5px rgba(0, 0, 0, .14), 0 3px 5
/// @prop - Background color of the ripple on the button
$button-md-ripple-background-color: #555 !default;
/// @prop - Background color of the focused button
$button-md-background-color-focused: color-shade($button-md-background-color, 12%) !default;
// Material Design Large Button
// --------------------------------------------------
@@ -156,6 +159,9 @@ $button-md-outline-opacity-activated: 1 !default;
/// @prop - Background color of the ripple on the outline button
$button-md-outline-ripple-background-color: $button-md-background-color !default;
/// @prop - Background color of the focused outline button
$button-md-outline-background-color-focused: rgba($button-md-background-color, 0.12) !default;
// Material Design Clear Button
// --------------------------------------------------
@@ -187,6 +193,9 @@ $button-md-clear-background-color-hover: rgba(158, 158, 158, .1) !default
/// @prop - Background color of the ripple on the clear button
$button-md-clear-ripple-background-color: #999 !default;
/// @props - Background color of the focused clear button
$button-md-clear-background-color-focused: rgba($button-md-background-color, 0.12) !default;
// Material Design Round Button
// --------------------------------------------------

View File

@@ -32,6 +32,11 @@
contain: content;
}
.button:active,
.button:focus {
outline: none;
}
.button-inner {
display: flex;

View File

@@ -1,4 +1,5 @@
import { Component, Element, Prop } from '@stencil/core';
import { BlurEvent, FocusEvent } from '../../utils/input-interfaces';
import { Component, Element, Event, EventEmitter, Prop, State } from '@stencil/core';
import { getElementClassObject } from '../../utils/theme';
@@ -12,6 +13,8 @@ import { getElementClassObject } from '../../utils/theme';
export class Button {
@Element() private el: HTMLElement;
@State() keyFocus: boolean;
/**
* Contains a URL or a URL fragment that the hyperlink points to.
* If this property is set, an anchor tag will be rendered.
@@ -72,6 +75,29 @@ export class Button {
*/
@Prop() mode: 'ios' | 'md';
/**
* Emitted when the button has focus.
*/
@Event() ionFocus: EventEmitter<FocusEvent>;
/**
* Emitted when the button loses focus.
*/
@Event() ionBlur: EventEmitter<BlurEvent>;
onFocus() {
this.ionFocus.emit();
}
onKeyUp() {
this.keyFocus = true;
}
onBlur() {
this.keyFocus = false;
this.ionBlur.emit();
}
protected render() {
const {
@@ -99,18 +125,25 @@ export class Button {
const buttonClasses = {
...getElementClassObject(this.el.classList),
...getElementClassObject(elementClasses)
...getElementClassObject(elementClasses),
'focused': this.keyFocus
};
return (
<TagType class={buttonClasses} disabled={this.disabled} href={this.href}>
<span class='button-inner'>
<slot name='icon-only'></slot>
<slot name='start'></slot>
<slot></slot>
<slot name='end'></slot>
</span>
<div class='button-effect'></div>
<TagType
class={buttonClasses}
disabled={this.disabled}
href={this.href}
onFocus={this.onFocus.bind(this)}
onKeyUp={this.onKeyUp.bind(this)}
onBlur={this.onBlur.bind(this)}>
<span class='button-inner'>
<slot name='icon-only'></slot>
<slot name='start'></slot>
<slot></slot>
<slot name='end'></slot>
</span>
<div class='button-effect'></div>
</TagType>
);
}

View File

@@ -240,6 +240,18 @@ boolean
If true, activates a button with a heavier font weight.
## Events
#### ionBlur
Emitted when the button loses focus.
#### ionFocus
Emitted when the button has focus.
----------------------------------------------

View File

@@ -12,31 +12,29 @@ template {
}
// Focus Outline
// Click Block
// --------------------------------------------------
// Fill the screen to block clicks (a better pointer-events: none)
// to avoid full-page reflows and paints which can cause flickers
$focus-outline-border-color: #51a7e8 !default;
$focus-outline-border-width: 2px !default;
$focus-outline-box-shadow: 0 0 8px 1px $focus-outline-border-color !default;
:focus,
:active {
outline: none;
.click-block {
display: none;
}
.focus-outline :focus {
outline: thin dotted;
outline-offset: -1px;
.click-block-enabled {
@include position(0, 0, 0, 0);
@include transform(translate3d(0, -100%, 0), translateY(1px));
position: absolute;
z-index: $z-index-click-block;
display: block;
opacity: 0;
contain: strict;
}
.focus-outline button:focus,
.focus-outline [ion-button]:focus {
border-color: $focus-outline-border-color;
outline: $focus-outline-border-width solid $focus-outline-border-color;
box-shadow: $focus-outline-box-shadow;
}
ion-input :focus {
outline: none;
.click-block-active {
@include transform(translate3d(0, 0, 0));
}