Skip to content

Commit

Permalink
feat(switch): add ripple to switch
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 474893973
  • Loading branch information
material-web-copybara authored and copybara-github committed Sep 16, 2022
1 parent 32963e2 commit 4a8c333
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 2 deletions.
56 changes: 56 additions & 0 deletions switch/lib/_switch-handle-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

@use 'sass:map';

@use '@material/web/ripple/ripple-theme';

$_selected: '.md3-switch--selected';
$_unselected: '.md3-switch--unselected';

Expand All @@ -23,6 +25,10 @@ $_unselected: '.md3-switch--unselected';
@include _handle-unselected($theme);
}
}

.md3-switch__ripple {
@include _ripple($theme);
}
}

@mixin _handle-container($theme) {
Expand Down Expand Up @@ -135,3 +141,53 @@ $_unselected: '.md3-switch--unselected';
background-color: map.get($colors, disabled);
}
}

@mixin _ripple($theme) {
@include _state-layer-size(map.get($theme, state-layer-size));
@include _state-layer-color($theme);
}

@mixin _state-layer-size($size) {
height: $size;
width: $size;
}

@mixin _state-layer-color($theme) {
#{$_selected} & {
@include ripple-theme.theme(
(
hover-state-layer-color:
map.get($theme, selected-hover-state-layer-color),
focus-state-layer-color:
map.get($theme, selected-focus-state-layer-color),
pressed-state-layer-color:
map.get($theme, selected-pressed-state-layer-color),
hover-state-layer-opacity:
map.get($theme, selected-hover-state-layer-opacity),
focus-state-layer-opacity:
map.get($theme, selected-focus-state-layer-opacity),
pressed-state-layer-opacity:
map.get($theme, selected-pressed-state-layer-opacity),
)
);
}

#{$_unselected} & {
@include ripple-theme.theme(
(
hover-state-layer-color:
map.get($theme, unselected-hover-state-layer-color),
focus-state-layer-color:
map.get($theme, unselected-focus-state-layer-color),
pressed-state-layer-color:
map.get($theme, unselected-pressed-state-layer-color),
hover-state-layer-opacity:
map.get($theme, unselected-hover-state-layer-opacity),
focus-state-layer-opacity:
map.get($theme, unselected-focus-state-layer-opacity),
pressed-state-layer-opacity:
map.get($theme, unselected-pressed-state-layer-opacity),
)
);
}
}
9 changes: 9 additions & 0 deletions switch/lib/_switch.scss
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ $icon-enter-duration: $animation-duration - $icon-exit-duration;
}
}

// Ripple
.md3-switch__ripple {
position: absolute;
display: inline-flex;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}

// Icons
.md3-switch__icons {
@include _icons;
Expand Down
38 changes: 36 additions & 2 deletions switch/lib/switch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
*/

import '@material/web/focus/focus-ring.js';
import '@material/web/ripple/ripple.js';

import {ActionElement, EndPressConfig} from '@material/web/actionelement/action-element.js';
import {ActionElement, EndPressConfig, BeginPressConfig} from '@material/web/actionelement/action-element.js';
import {ariaProperty as legacyAriaProperty} from '@material/web/compat/base/aria-property.js'; // TODO(b/236840525): remove compat dependencies
import {FormController, getFormValue} from '@material/web/controller/form-controller.js';
import {ariaProperty} from '@material/web/decorators/aria-property.js';
import {pointerPress as focusRingPointerPress, shouldShowStrongFocus} from '@material/web/focus/strong-focus.js';
import {MdRipple} from '@material/web/ripple/ripple.js';
import {html, TemplateResult} from 'lit';
import {eventOptions, property, state} from 'lit/decorators.js';
import {eventOptions, property, query, state} from 'lit/decorators.js';
import {ClassInfo, classMap} from 'lit/directives/class-map.js';
import {ifDefined} from 'lit/directives/if-defined.js';

Expand Down Expand Up @@ -41,6 +43,9 @@ export class Switch extends ActionElement {

@state() protected showFocusRing = false;

// Ripple
@query('md-ripple') readonly ripple!: MdRipple;

// FormController
get form() {
return this.closest('form');
Expand Down Expand Up @@ -80,6 +85,7 @@ export class Switch extends ActionElement {
@focus="${this.handleFocus}"
@blur="${this.handleBlur}"
@pointerdown=${this.handlePointerDown}
@pointerenter=${this.handlePointerEnter}
@pointerup=${this.handlePointerUp}
@pointercancel=${this.handlePointerCancel}
@pointerleave=${this.handlePointerLeave}
Expand Down Expand Up @@ -111,6 +117,18 @@ export class Switch extends ActionElement {
};
}

/** @soyTemplate */
protected renderRipple(): TemplateResult {
return html`
<div class="md3-switch__ripple">
<md-ripple
?disabled="${this.disabled}"
unbounded>
</md-ripple>
</div>
`;
}

/** @soyTemplate */
protected renderFocusRing(): TemplateResult {
return html`<md-focus-ring .visible="${
Expand All @@ -125,6 +143,7 @@ export class Switch extends ActionElement {
};
return html`
<div class="md3-switch__handle-container">
${this.renderRipple()}
<div class="md3-switch__handle ${classMap(classes)}">
${this.shouldShowIcons() ? this.renderIcons() : html``}
</div>
Expand Down Expand Up @@ -179,7 +198,13 @@ export class Switch extends ActionElement {
return this.icons || this.showOnlySelectedIcon;
}

override beginPress({positionEvent}: BeginPressConfig) {
this.ripple.beginPress(positionEvent);
}

override endPress({cancelled}: EndPressConfig) {
this.ripple.endPress();

if (cancelled || this.disabled) {
return;
}
Expand All @@ -196,6 +221,15 @@ export class Switch extends ActionElement {
this.showFocusRing = false;
}

protected handlePointerEnter(e: PointerEvent) {
this.ripple.beginHover(e);
}

override handlePointerLeave(e: PointerEvent) {
super.handlePointerLeave(e);
this.ripple.endHover();
}

@eventOptions({passive: true})
override handlePointerDown(event: PointerEvent) {
super.handlePointerDown(event);
Expand Down

0 comments on commit 4a8c333

Please sign in to comment.