vue-directive-ripple
vue-directive-ripple
A Vue 3 plugin that adds a v-ripple directive to bring the Material Design ripple effect to your elements.
- 🎯 One directive, zero configuration to get started.
- 🎨 Styled via a CSS custom property, no theming API to learn.
- 🧩 Supports both Material Design 2 and Material Design 3 appearances.
- 📦 TypeScript-first, with type hints available out of the box.
- 🛢️ Compatible with SSR.
Installation
# npm
npm install vue-directive-ripple
# yarn
yarn add vue-directive-ripple
# pnpm
pnpm add vue-directive-ripple
# bun
bun add vue-directive-ripple
Quick start
Vue.js
Register the plugin in your entry file:
import { createApp } from "vue";
import VRipplePlugin from "vue-directive-ripple";
import App from "./App.vue";
const app = createApp(App);
app.use(VRipplePlugin, { /* Options */ });
app.mount("#app");
The stylesheet is imported automatically by the plugin, so there is nothing else to import.
Then just add v-ripple to any element:
<button v-ripple>Click me</button>
Nuxt
If you are using Nuxt (2 and above), here is how to register the plugin.
- Firstly, inside your project's root, find or create a
plugins/folder. Create a new TypeScript or JavaScript file that calledripple.tsorripple.jsinside it.
// plugins/ripple.ts
import VRipplePlugin from "vue-directive-ripple";
export default defineNuxtPlugin(nuxtApp => {
nuxtApp.vueApp.use(VRipplePlugin, { /* Options */ });
});
- Secondly, register that nuxt plugin in your nuxt config file.
// nuxt.config.ts
export default defineNuxtConfig({
plugins: [
"plugins/ripple.ts",
],
});
TypeScript
If you are using TypeScript, import the client entry in your project to get type hints for the v-ripple directive:
Recommended for TypeScript 6.0+ — add "vue-directive-ripple/client" to the types array in your tsconfig.json:
// tsconfig.json
{
"compilerOptions": {
"types": [
"vue-directive-ripple/client"
]
}
}
Recommended for TypeScript < 6.0 — add a triple-slash reference to your env.d.ts (or vite-env.d.ts, create it if it does not exist):
// env.d.ts
/// <reference types="vite/client" />
/// <reference types="vue-directive-ripple/client" />
The plugin's default export is fully typed, and its options type is also exported for your convenience:
import type { VRipplePluginOptions } from "vue-directive-ripple";
Usage
Basic usage
Apply the ripple directly on an element:
<button v-ripple>Click me</button>
Toggling the ripple
The v-ripple directive also accepts a boolean value:
<button v-ripple="true">I have ripple effect</button>
<button v-ripple="false">I don't have ripple effect</button>
Pass a boolean variable to dynamically control whether the ripple is enabled:
<script setup>
const enableRipple = ref(true);
</script>
<template>
<button v-ripple="enableRipple">Click me</button>
</template>
When the value is false, no ripple will be triggered.
The overlay modifier
By default, the target element gets an overflow: clip style that clips its children. Use the overlay modifier to skip that, so the element's children can extend beyond its bounds:
<button v-ripple.overlay>Click me</button>
Customizing the color
To change the ripple color, set the --ripple CSS custom property on the target element:
.my-button {
--ripple: rgb(255 0 0 / 15%);
}
<button class="my-button" v-ripple>Click me</button>
Or just:
<button v-ripple style="--ripple: rgb(255 0 0 / 15%);">Click me</button>
Declare it on :root to control the color of every ripple at once:
:root {
--ripple: rgb(255 0 0 / 15%);
}
If no color is defined, the ripple defaults to the element's current text color at 15% opacity.
Options
Pass options to the plugin's install to customize the ripple behavior:
import { createApp } from "vue";
import VRipplePlugin from "vue-directive-ripple";
import App from "./App.vue";
createApp(App).use(VRipplePlugin, {
rippleClass: "my-ripple",
materialDesignVersion: 3,
accelerateOnRelease: false,
spreadDuration: 800,
fadeDuration: 300,
});
| Option | Type | Default | Description |
|---|---|---|---|
rippleClass |
string |
"ripple" |
The class name applied to the ripple target element, also used as the prefix for the related elements' class names (e.g. -circle, -wrapper). |
materialDesignVersion |
2 | 3 |
2 |
Which Material Design version the ripple appearance should follow. 2 has a sharp circle edge, 3 a smooth one. |
accelerateOnRelease |
boolean |
true |
Whether the spread animation speeds up when the pointer is released. true mimics Android 5.0–8.x, false mimics Android 9.0+. |
spreadDuration |
number |
1000 |
The duration of the spread (appearance) animation, in milliseconds. |
fadeDuration |
number |
500 |
The duration of the fade-out (disappearance) animation, in milliseconds. |
License
Related Packages
Lightweight package for highlighting menu items as you scroll the page, also scr...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 1.1.1 | ^3.5.42 | MIT | |
| 1.1.0 | ^3.5.42 | MIT | |
| 1.0.1 | ^3.5.42 | MIT |