nuxt-ripple
Version:
Add simple ripple effects to your elements
74 lines (73 loc) • 2.18 kB
JavaScript
import { computed, ref } from "vue";
import { addHeadStyles, unmountListeners, modeHandler, setAttributes } from "./utils.js";
import { defineNuxtPlugin, useAppConfig } from "#app";
class Ripple {
state;
listeners;
intervals;
mode;
color;
duration;
scale;
pulseInterval;
overflow;
constructor() {
this.state = ref(useAppConfig().ripple);
this.listeners = /* @__PURE__ */ new Map();
this.intervals = /* @__PURE__ */ new Map();
this.mode = computed(() => this.state.value.mode);
this.color = computed(() => this.state.value.color);
this.duration = computed(() => this.state.value.duration);
this.scale = computed(() => this.state.value.scale);
this.pulseInterval = computed(() => this.state.value.pulseInterval);
this.overflow = computed(() => this.state.value.overflow);
}
mount(config) {
this.state.value = config || this.state.value;
if (!import.meta.client) return;
addHeadStyles(this.state.value);
const selector = document.querySelectorAll('[data-ripple-bound="true"]');
for (const el of selector) {
unmountListeners(el, this.listeners, this.intervals);
modeHandler(el, this.state.value, this.listeners, this.intervals);
}
}
}
export default defineNuxtPlugin((nuxtApp) => {
const ripple = new Ripple();
nuxtApp.hook("app:mounted", () => {
ripple.mount();
});
nuxtApp.vueApp.directive("ripple", {
beforeMount(el, binding) {
el.dataset.rippleBound = "true";
setAttributes(el, binding.value);
},
mounted(el) {
modeHandler(el, ripple.state.value, ripple.listeners, ripple.intervals);
},
updated(el, binding) {
setAttributes(el, binding.value);
},
unmounted(el) {
unmountListeners(el, ripple.listeners, ripple.intervals);
},
getSSRProps() {
return {};
}
});
return {
provide: {
ripple: {
state: ripple.state,
mode: ripple.mode,
color: ripple.color,
duration: ripple.duration,
scale: ripple.scale,
pulseInterval: ripple.pulseInterval,
overflow: ripple.overflow,
mount: ripple.mount.bind(ripple)
}
}
};
});