@sandlada/mdc
Version:
@sandlada/mdc is an open source component library that follows the Material Design 3 design specifications.
11 lines (10 loc) • 4.58 kB
JavaScript
import{E as t}from"../../easing-5hHInU7b.js";import"../../lit-element-Ho-VPzO1.js";
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
* @link
* https://github.com/material-components/material-web/blob/main/ripple/internal/ripple.ts
*
* [Modified by Kai-Orion & Sandlada]
*/const e=0,i=1,s=2,n=3,o=550,h=250,r=.2,a=10,l=75,d=.35,c="forwards",u=150,p=["click","contextmenu","pointercancel","pointerdown","pointerenter","pointerleave","pointerup","focus","blur"];class m{constructor(t){this.state=e,this.startEvent=null,this.checkBoundsAfterContextMenu=!1,this.initialSize=0,this.rippleScale="",this.rippleSize="",this.growAnimation=null,this.handleEvent=async t=>{switch(t.type){case"click":this.handleClick();break;case"contextmenu":this.handleContextmenu();break;case"pointercancel":this.handlePointercancel(t);break;case"pointerdown":await this.handlePointerdown(t);break;case"pointerenter":this.handlePointerenter(t);break;case"pointerleave":this.handlePointerleave(t);break;case"pointerup":this.handlePointerup(t);break;case"focus":this.handleFocus();break;case"blur":this.handleBlur()}},this.host=t}onControlChange(t,e){for(const i of p)t?.removeEventListener(i,this.handleEvent),e?.addEventListener(i,this.handleEvent)}handlePointerenter(t){this.shouldReactToEvent(t)&&(this.host.hovered=!0)}handlePointerleave(t){this.shouldReactToEvent(t)&&(this.host.hovered=!1,this.state!==e&&this.endPressAnimation())}handlePointerup(t){if(this.shouldReactToEvent(t)){if(this.state!==s)return this.state===i?(this.state=n,void this.startPressAnimation(this.startEvent||void 0)):void 0;this.state=n}}async handlePointerdown(t){if(this.shouldReactToEvent(t)){if(this.startEvent=t,!this.isTouch(t))return this.state=n,void this.startPressAnimation(t);this.checkBoundsAfterContextMenu&&!this.inBounds(t)||(this.checkBoundsAfterContextMenu=!1,this.state=i,await new Promise(t=>{setTimeout(t,u)}),this.state===i&&(this.state=s,this.startPressAnimation(t)))}}handlePointercancel(t){this.shouldReactToEvent(t)&&this.endPressAnimation()}handleClick(){this.host.disabled||(this.state!==n?this.state===e&&(this.startPressAnimation(),this.endPressAnimation()):this.endPressAnimation())}handleContextmenu(){this.host.disabled||(this.checkBoundsAfterContextMenu=!0,this.endPressAnimation())}handleFocus(){this.host.disabled||(this.host.focused=!0)}handleBlur(){this.host.disabled||(this.host.focused=!1,this.state!==e&&this.endPressAnimation())}startPressAnimation(e){this.host.pressed=!0,this.growAnimation?.cancel(),this.determineRippleSize();const{startPoint:i,endPoint:s}=this.getTranslationCoordinates(e),n=`${i.x}px, ${i.y}px`,h=`${s.x}px, ${s.y}px`;null!==this.host&&(this.growAnimation=this.host.pressStateLayerElement.animate({top:[0,0],left:[0,0],height:[this.rippleSize,this.rippleSize],width:[this.rippleSize,this.rippleSize],transform:[`translate(${n}) scale(1)`,`translate(${h}) scale(${this.rippleScale})`]},{duration:o,easing:t.Standard,fill:c}))}getTranslationCoordinates(t){if(null===this.host)return;const{height:e,width:i}=this.host.getBoundingClientRect(),s={x:(i-this.initialSize)/2,y:(e-this.initialSize)/2};let n={x:i/2,y:e/2};return t instanceof PointerEvent&&(n=this.getNormalizedPointerEventCoords(t)),n={x:n.x-this.initialSize/2,y:n.y-this.initialSize/2},{startPoint:n,endPoint:s}}getNormalizedPointerEventCoords(t){if(null===this.host)return;const{scrollX:e,scrollY:i}=window,{left:s,top:n}=this.host.getBoundingClientRect(),o=e+s,h=i+n,{pageX:r,pageY:a}=t;return{x:r-o,y:a-h}}async endPressAnimation(){this.state=e;const t=this.growAnimation;let i=1/0;"number"==typeof t?.currentTime?i=t.currentTime:t?.currentTime&&(i=t.currentTime.to("ms").value),i>=h?this.host.pressed=!1:(await new Promise(t=>{setTimeout(t,h-i)}),this.growAnimation===t&&(this.host.pressed=!1))}determineRippleSize(){if(null===this.host)return;const{height:t,width:e}=this.host.getBoundingClientRect(),i=Math.max(t,e),s=Math.max(d*i,l),n=Math.floor(i*r),o=Math.sqrt(e**2+t**2)+a;this.initialSize=n,this.rippleScale=""+(o+s)/this.initialSize,this.rippleSize=`${this.initialSize}px`}inBounds({x:t,y:e}){if(null===this.host)return;const{top:i,left:s,bottom:n,right:o}=this.host.getBoundingClientRect();return t>=s&&t<=o&&e>=i&&e<=n}isTouch({pointerType:t}){return"touch"===t}shouldReactToEvent(t){if(this.host.disabled||!t.isPrimary)return!1;if(this.startEvent&&this.startEvent.pointerId!==t.pointerId)return!1;if("pointerenter"===t.type||"pointerleave"===t.type)return!this.isTouch(t);const e=1===t.buttons;return this.isTouch(t)||e}}export{m as RippleAction};