UNPKG

@featherds/ripple

Version:

A wee ripple.

110 lines (109 loc) 2.9 kB
import { defineComponent, h } from "vue"; import { _clearTimeout, _setTimeout } from "@featherds/utils/setTimeout"; const props = { center: { type: Boolean, default: false } }; const _sfc_main = defineComponent({ props, data() { return { pressed: false, active: false, styles: {}, failsafe: -1 }; }, computed: { parent() { return this.$el.parentNode; } }, methods: { onClick($event) { this.pressed = false; this.active = false; requestAnimationFrame(() => { const { clientWidth, clientHeight } = this.parent; const size = Math.round(Math.max(clientWidth, clientHeight)); let position = { top: "0px", left: "0px" }; if (!this.center) { const rect = this.parent.getBoundingClientRect(); const top = $event.pageY; const left = $event.pageX; position = { top: `${top - rect.top - size / 2 - document.documentElement.scrollTop}px`, left: `${left - rect.left - size / 2 - document.documentElement.scrollLeft}px` }; } this.styles = { ...position, height: `${size}px`, width: `${size}px` }; this.pressed = true; requestAnimationFrame(() => { this.active = true; _clearTimeout(this.failsafe); this.failsafe = _setTimeout(() => { this.pressed = false; this.active = false; }, 380 + 100 + 20); }); }); }, cleanupEventListeners() { if (this.parent) { this.parent.removeEventListener("click", this.onClick); } } }, render() { if (this.pressed === false) { return void 0; } return h("div", { style: { ...this.styles }, class: ["ripple", { active: this.active, center: this.center }], onTransitionEnd: () => { this.pressed = false; this.active = false; }, onTransitionCancel: () => { this.pressed = false; this.active = false; } }); }, mounted() { this.parent.addEventListener("click", this.onClick); const parentStyles = window.getComputedStyle(this.parent); this.parent.style.overflow = "hidden"; if (parentStyles.position === "relative" || parentStyles.position === "absolute" || parentStyles.position === "fixed") { return; } this.parent.style.position = "relative"; }, beforeUnmount() { this.cleanupEventListeners(); }, unmounted() { this.cleanupEventListeners(); } }); const _export_sfc = (sfc, props2) => { const target = sfc.__vccOpts || sfc; for (const [key, val] of props2) { target[key] = val; } return target; }; const FeatherRipple = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-bcadad4b"]]); export { FeatherRipple };