@universal-material/web
Version:
Material web components
120 lines • 4.68 kB
JavaScript
var UmRipple_1;
import { __decorate } from "tslib";
import { html, LitElement } from 'lit';
import { customElement, property, query } from 'lit/decorators.js';
import { styles } from './ripple.styles.js';
let UmRipple = class UmRipple extends LitElement {
static { UmRipple_1 = this; }
static { this.styles = styles; }
constructor() {
super();
this.isTouching = false;
/**
* Disables the ripple.
*/
this.disabled = false;
}
render() {
return html `<div class="ripple-container"></div><slot></slot>`;
}
connectedCallback() {
super.connectedCallback();
this.attachEvents();
this.ariaHidden = 'true';
}
disconnectedCallback() {
super.disconnectedCallback();
this.dettachEvents();
}
attachEvents() {
this.addEventListener('mousedown', this.handleMouseDown);
this.addEventListener('touchstart', this.handleTouchStart);
}
dettachEvents() {
this.removeEventListener('mousedown', this.handleMouseDown);
this.removeEventListener('touchstart', this.handleTouchStart);
}
handleMouseDown(e) {
if (this.isTouching || !this.canCreateRipple()) {
return;
}
this.createRipple(e.clientX, e.clientY, 'mouseup');
}
handleTouchStart(e) {
if (!this.canCreateRipple()) {
return;
}
this.isTouching = true;
const dismiss = this.createRipple(e.touches[0].clientX, e.touches[0].clientY, 'touchend');
this.addEventListener('touchmove', dismiss);
}
canCreateRipple() {
return !this.disabled;
}
createRipple(targetX = null, targetY = null, releaseEventName = null) {
const preClientRect = this.rippleContainer.getBoundingClientRect();
targetX ??= preClientRect.x + this.rippleContainer.clientWidth / 2;
targetY ??= preClientRect.y + this.rippleContainer.clientHeight / 2;
const ripple = document.createElement('DIV');
ripple.classList.add('ripple');
this.rippleContainer.appendChild(ripple);
requestAnimationFrame(() => {
const clientRect = this.getBoundingClientRect();
const largestDimensionSize = Math.max(this.clientWidth, this.clientHeight);
const rippleSize = largestDimensionSize * 2;
UmRipple_1._setElementSquareSizeAndCenter(ripple, rippleSize);
ripple.style.setProperty('--_ripple-transition-duration', `${1080 * Math.pow(rippleSize, 0.3)}ms`);
const x = (targetX - clientRect.left) + ((rippleSize - this.rippleContainer.clientWidth) / 2);
const y = (targetY - clientRect.top) + ((rippleSize - this.rippleContainer.clientHeight) / 2);
ripple.style.transformOrigin = `${x}px ${y}px`;
ripple.classList.add(releaseEventName ? 'show' : 'show-forced');
});
const interval = setInterval(() => {
if (!ripple.classList.contains('dismiss') && !ripple.classList.contains('show-forced')) {
return;
}
const animations = ripple.getAnimations();
if (animations.length) {
return;
}
clearInterval(interval);
ripple.remove();
}, 1000);
if (!releaseEventName) {
return null;
}
return this.createDismissEvent(ripple, releaseEventName);
}
createDismissEvent(ripple, releaseEventName) {
const dismiss = () => {
ripple.classList.add('dismiss');
this.isTouching = false;
this.removeEventListener('dragover', dismiss);
this.removeEventListener('mouseleave', dismiss);
window.removeEventListener(releaseEventName, dismiss);
};
this.addEventListener('dragover', dismiss);
this.addEventListener('mouseleave', dismiss);
window.addEventListener(releaseEventName, dismiss);
return dismiss;
}
static _setElementSquareSizeAndCenter(element, size) {
element.style.top = '50%';
element.style.left = '50%';
element.style.width = `${size}px`;
element.style.height = `${size}px`;
element.style.marginLeft = `${-size / 2}px`;
element.style.marginTop = `${-size / 2}px`;
}
};
__decorate([
property({ type: Boolean, reflect: true })
], UmRipple.prototype, "disabled", void 0);
__decorate([
query('.ripple-container')
], UmRipple.prototype, "rippleContainer", void 0);
UmRipple = UmRipple_1 = __decorate([
customElement('u-ripple')
], UmRipple);
export { UmRipple };
//# sourceMappingURL=ripple.js.map