UNPKG

@varlet/ui

Version:

A Vue3 component library based on Material Design 2 and 3, supporting mobile and desktop.

175 lines (172 loc) • 6.43 kB
var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); import { getRect, getStyle, supportTouch } from "@varlet/shared"; import context from "../context/index.mjs"; import { createNamespace } from "../utils/components.mjs"; const { n } = createNamespace("ripple"); const ANIMATION_DURATION = 250; function setStyles(element) { const { zIndex, position } = getStyle(element); element.style.overflow = "hidden"; element.style.overflowX = "hidden"; element.style.overflowY = "hidden"; position === "static" && (element.style.position = "relative"); zIndex === "auto" && (element.style.zIndex = "1"); } function isTouchEvent(event) { return "touches" in event; } function computeRippleStyles(element, event) { const { top, left } = getRect(element); const { clientWidth, clientHeight } = element; const radius = Math.sqrt(clientWidth ** 2 + clientHeight ** 2) / 2; const size = radius * 2; const localX = isTouchEvent(event) ? event.touches[0].clientX - left : clientWidth / 2; const localY = isTouchEvent(event) ? event.touches[0].clientY - top : clientHeight / 2; const centerX = (clientWidth - radius * 2) / 2; const centerY = (clientHeight - radius * 2) / 2; const x = localX - radius; const y = localY - radius; return { x, y, centerX, centerY, size }; } function createRipple(event) { const _ripple = this._ripple; _ripple.removeRipple(); if (_ripple.disabled || _ripple.tasker || !context.enableRipple) { return; } const task = () => { _ripple.tasker = null; const { x, y, centerX, centerY, size } = computeRippleStyles(this, event); const ripple = document.createElement("div"); ripple.classList.add(n()); ripple.style.opacity = `0`; ripple.style.transform = `translate(${x}px, ${y}px) scale3d(.3, .3, .3)`; ripple.style.width = `${size}px`; ripple.style.height = `${size}px`; _ripple.color && (ripple.style.backgroundColor = _ripple.color); ripple.dataset.createdAt = String(performance.now()); setStyles(this); this.appendChild(ripple); window.setTimeout(() => { ripple.style.transform = `translate(${centerX}px, ${centerY}px) scale3d(1, 1, 1)`; ripple.style.opacity = `.25`; }, 20); }; _ripple.tasker = window.setTimeout(task, 30); } function removeRipple() { const _ripple = this._ripple; const task = () => { const ripples = this.querySelectorAll(`.${n()}`); if (!ripples.length) { return; } const lastRipple = ripples[ripples.length - 1]; const delay = ANIMATION_DURATION - performance.now() + Number(lastRipple.dataset.createdAt); window.setTimeout(() => { lastRipple.style.opacity = `0`; window.setTimeout(() => { var _a; return (_a = lastRipple.parentNode) == null ? void 0 : _a.removeChild(lastRipple); }, ANIMATION_DURATION); }, delay); }; _ripple.tasker ? window.setTimeout(task, 30) : task(); } function forbidRippleTask() { if (!supportTouch() || !context.enableRipple) { return; } const _ripple = this._ripple; _ripple.tasker && window.clearTimeout(_ripple.tasker); _ripple.tasker = null; } let hasKeyboardRipple = false; function createKeyboardRipple(event) { if (hasKeyboardRipple || !(event.key === " " || event.key === "Enter")) { return; } createRipple.call(this, event); hasKeyboardRipple = true; } function removeKeyboardRipple() { if (!hasKeyboardRipple) { return; } removeRipple.call(this); hasKeyboardRipple = false; } function mounted(el, binding) { var _a; el._ripple = __spreadProps(__spreadValues({ tasker: null }, (_a = binding.value) != null ? _a : {}), { removeRipple: removeRipple.bind(el) }); el.addEventListener("touchstart", createRipple, { passive: true }); el.addEventListener("touchmove", forbidRippleTask, { passive: true }); el.addEventListener("dragstart", removeRipple, { passive: true }); el.addEventListener("keydown", createKeyboardRipple); el.addEventListener("keyup", removeKeyboardRipple); el.addEventListener("blur", removeKeyboardRipple); document.addEventListener("touchend", el._ripple.removeRipple, { passive: true }); document.addEventListener("touchcancel", el._ripple.removeRipple, { passive: true }); document.addEventListener("dragend", el._ripple.removeRipple, { passive: true }); } function unmounted(el) { el.removeEventListener("touchstart", createRipple); el.removeEventListener("touchmove", forbidRippleTask); el.removeEventListener("dragstart", removeRipple); if (!el._ripple || !el._ripple.removeRipple) { return; } document.removeEventListener("touchend", el._ripple.removeRipple); document.removeEventListener("touchcancel", el._ripple.removeRipple); document.removeEventListener("dragend", el._ripple.removeRipple); } function updated(el, binding) { var _a, _b, _c, _d, _e, _f; const newBinding = { color: (_a = binding.value) == null ? void 0 : _a.color, disabled: (_b = binding.value) == null ? void 0 : _b.disabled }; const diff = newBinding.color !== ((_c = el._ripple) == null ? void 0 : _c.color) || newBinding.disabled !== ((_d = el._ripple) == null ? void 0 : _d.disabled); if (diff) { el._ripple = __spreadValues({ tasker: newBinding.disabled ? null : (_e = el._ripple) == null ? void 0 : _e.tasker, removeRipple: (_f = el._ripple) == null ? void 0 : _f.removeRipple }, newBinding); } } const Ripple = { mounted, unmounted, updated, install(app) { app.directive("ripple", this); } }; const _RippleComponent = Ripple; var stdin_default = Ripple; export { _RippleComponent, stdin_default as default };