UNPKG

@smui/ripple

Version:

Svelte Material UI - Ripple

154 lines 6.74 kB
import { MDCRippleFoundation, util } from '@material/ripple'; import { events, ponyfill } from '@material/dom'; import { getContext } from 'svelte'; import { SvelteEventManager } from '@smui/common/internal'; const { applyPassive } = events; const { matches } = ponyfill; export default function Ripple(node, { ripple = true, surface = false, unbounded = false, disabled = false, color, active, rippleElement, eventTarget, activeTarget, addClass = (className) => node.classList.add(className), removeClass = (className) => node.classList.remove(className), addStyle = (name, value) => node.style.setProperty(name, value), initPromise = Promise.resolve(), } = {}) { let instance; let eventManager = new SvelteEventManager(); let addLayoutListener = getContext('SMUI:addLayoutListener'); let removeLayoutListener; let oldActive = active; let oldEventTarget = eventTarget; let oldActiveTarget = activeTarget; function handleProps() { if (surface) { addClass('mdc-ripple-surface'); if (color === 'primary') { addClass('smui-ripple-surface--primary'); removeClass('smui-ripple-surface--secondary'); } else if (color === 'secondary') { removeClass('smui-ripple-surface--primary'); addClass('smui-ripple-surface--secondary'); } else { removeClass('smui-ripple-surface--primary'); removeClass('smui-ripple-surface--secondary'); } } else { removeClass('mdc-ripple-surface'); removeClass('smui-ripple-surface--primary'); removeClass('smui-ripple-surface--secondary'); } // Handle activation first. if (instance && oldActive !== active) { oldActive = active; if (active) { instance.activate(); } else if (active === false) { instance.deactivate(); } } // Then create/destroy an instance. if (ripple && !instance) { instance = new MDCRippleFoundation({ addClass, browserSupportsCssVars: () => util.supportsCssVariables(window), computeBoundingRect: () => (rippleElement || node).getBoundingClientRect(), containsEventTarget: (target) => node.contains(target), deregisterDocumentInteractionHandler: (evtType, handler) => eventManager.off(document.documentElement, evtType, handler), deregisterInteractionHandler: (evtType, handler) => eventManager.off(eventTarget || node, evtType, handler), deregisterResizeHandler: (handler) => window.removeEventListener('resize', handler), getWindowPageOffset: () => { var _a, _b; return ({ x: (_a = window.pageXOffset) !== null && _a !== void 0 ? _a : window.scrollX, y: (_b = window.pageYOffset) !== null && _b !== void 0 ? _b : window.scrollY, }); }, isSurfaceActive: () => active == null ? matches(activeTarget || node, ':active') : active, isSurfaceDisabled: () => !!disabled, isUnbounded: () => !!unbounded, registerDocumentInteractionHandler: (evtType, handler) => { const opts = applyPassive(); eventManager.on(document.documentElement, evtType, handler, typeof opts === 'boolean' ? { capture: opts } : opts); }, registerInteractionHandler: (evtType, handler) => { const opts = applyPassive(); eventManager.on(eventTarget || node, evtType, handler, typeof opts === 'boolean' ? { capture: opts } : opts); }, registerResizeHandler: (handler) => eventManager.on(window, 'resize', handler), removeClass, updateCssVariable: addStyle, }); initPromise.then(() => { if (instance) { instance.init(); instance.setUnbounded(unbounded); } }); } else if (instance && !ripple) { initPromise.then(() => { if (instance) { instance.destroy(); instance = undefined; eventManager.clear(); } }); } // Now handle event/active targets if (instance && (oldEventTarget !== eventTarget || oldActiveTarget !== activeTarget)) { oldEventTarget = eventTarget; oldActiveTarget = activeTarget; instance.destroy(); requestAnimationFrame(() => { if (instance) { instance.init(); instance.setUnbounded(unbounded); } }); } if (!ripple && unbounded) { addClass('mdc-ripple-upgraded--unbounded'); } } handleProps(); if (addLayoutListener) { removeLayoutListener = addLayoutListener(layout); } function layout() { if (instance) { instance.layout(); } } return { update(props) { ({ ripple, surface, unbounded, disabled, color, active, rippleElement, eventTarget, activeTarget, addClass, removeClass, addStyle, initPromise, } = Object.assign({ ripple: true, surface: false, unbounded: false, disabled: false, color: undefined, active: undefined, rippleElement: undefined, eventTarget: undefined, activeTarget: undefined, addClass: (className) => node.classList.add(className), removeClass: (className) => node.classList.remove(className), addStyle: (name, value) => node.style.setProperty(name, value), initPromise: Promise.resolve() }, props)); handleProps(); }, destroy() { if (instance) { instance.destroy(); instance = undefined; eventManager.clear(); removeClass('mdc-ripple-surface'); removeClass('smui-ripple-surface--primary'); removeClass('smui-ripple-surface--secondary'); } if (removeLayoutListener) { removeLayoutListener(); } }, }; } //# sourceMappingURL=Ripple.js.map