Click

A visual effect played where the pointer clicks: a ring, a ripple, a crosshair, a burst or particles.

<script setup lang="ts">
import type { ClickVariant } from '@animate-ui/vue/primitives/effects/click'
import { Click } from '@animate-ui/vue/primitives/effects/click'
import { cn } from 'cn'
import { computed, ref } from 'vue'

const props = withDefaults(
  defineProps<{ global?: boolean | string, duration?: number | string, size?: number | string }>(),
  { global: false, duration: 400, size: 100 },
)

const VARIANTS: ClickVariant[] = ['ring', 'ripple', 'crosshair', 'burst', 'particles']
const scopeElement = ref<HTMLElement | null>(null)
const variant = ref<ClickVariant>('ring')
const scope = computed(() =>
  props.global === true || props.global === 'true' ? undefined : scopeElement.value,
)
</script>

<template>
  <div class="flex w-full max-w-md flex-col gap-3">
    <div
      ref="scopeElement"
      class="flex h-56 items-center justify-center rounded-xl border border-dashed text-foreground"
    >
      <Click
        :variant="variant"
        :scope="scope"
        :color="variant === 'ripple' ? 'var(--color-primary)' : 'currentColor'"
        :size="Number(size)"
        :duration="Number(duration)"
      >
        <p class="text-lg font-medium text-muted-foreground select-none">
          Click anywhere in this area
        </p>
      </Click>
    </div>
    <div role="radiogroup" aria-label="Variant" class="flex flex-wrap justify-center gap-1">
      <button
        v-for="item in VARIANTS"
        :key="item"
        type="button"
        role="radio"
        :aria-checked="variant === item"
        :class="cn(
          'h-7 rounded-md px-2.5 text-xs font-medium capitalize transition-colors',
          variant === item ? 'bg-accent text-foreground' : 'text-muted-foreground hover:text-foreground',
        )"
        @click="variant = item"
      >
        {{ item }}
      </button>
    </div>
  </div>
</template>

Installation

npm install @animate-ui/vue motion-v
pnpm add @animate-ui/vue motion-v
yarn add @animate-ui/vue motion-v
bun add @animate-ui/vue motion-v

Usage

<script setup lang="ts">
import { ref } from 'vue';
import { Click } from '@animate-ui/vue/primitives/effects/click';

const area = ref<HTMLElement | null>(null);
</script>

<template>
  <div ref="area">
    <Click :scope="area" variant="ring">
      <p>Click anywhere</p>
    </Click>
  </div>
</template>

Without scope, every click on the page plays the effect.

Animation

  • On pointer up, the effect plays centered on the pointer, then is removed. It lasts duration (400ms by default); with variant="particles", the dots start one after another and finish a little later.
  • Effects render in a fixed layer over the page that never catches the pointer, so clicks still reach what's underneath.
  • Several clicks in a row each play their own effect.
  • Under reduced motion, no effect is played.

API Reference

Click

PropTypeDefault
variant?
'ring' | 'ripple' | 'crosshair' | 'burst' | 'particles''ring'
color?
string'currentColor'
size?
number100
duration?
number400
scope?
HTMLElement | null-
disabled?
booleanfalse
#default?
slot-

Credits

Built by Skyleen. The source code is available on GitHub.

Last updated: 10/23/2026