Most buttons just sit there and wait to be clicked. This one doesn't.
Wrium Evasive Button is a small plugin for Wrium that makes a button (or any interactive element) smoothly dodge the cursor when you get close. It's silly on purpose, but it turns out to be surprisingly useful.
Why would you want this?
- Smart form validation: the submit button stays out of reach until the required fields are valid
- Gamified forms and playful login screens
- Interactive confirmations where the "wrong" choice is hard to click
What you get
- Smooth, physics-style gliding along walls, with no teleporting or sticking at edges
- Movement limited to the parent, the viewport, or any element you choose
- Limits via
maxRadius,duration, andmaxAttempts, so the button eventually gives up and settles - Reactive toggling:
v-evade="{ active: !isFormValid }" - State classes and attributes for styling:
.is-evading,.is-settled,data-state -
@evade,@settle, and@giveupevents - Respects
prefers-reduced-motionand keeps keyboard navigation working (Tab+Enter/Space) - Zero dependencies
Install
npm install @wrium/evasive-button
@wrium/wrium is a peer dependency, so install it too if you haven't already.
Basic usage
<div id="app">
<button v-evade>Try to Click Me!</button>
</div>
<script type="module">
import { createApp } from '@wrium/wrium';
import { EvasiveButtonPlugin } from '@wrium/evasive-button';
createApp(() => ({}))
.use(EvasiveButtonPlugin)
.mount('#app');
</script>
That's it. The button now runs away from your mouse.
The practical version: form validation
Bind active to your form state. While the form is invalid the button dodges, and once it's valid the button glides back home, ready to be clicked:
<div id="button-arena">
<button
v-evade="{ active: !isFormValid, bounds: '#button-arena', maxRadius: 150 }"
>
{{ isFormValid ? 'Log In' : 'Fill fields first!' }}
</button>
</div>
You can also style it based on its state:
.login-btn.is-evading { background: #e11d48; }
A note on UX and accessibility
An evasive button is a fun UX trick, so use it with care. The plugin helps by respecting reduced-motion preferences, letting keyboard users submit normally, and giving up after a duration or number of attempts if you set those options. I'd still keep it for playful or low-stakes moments rather than critical flows.
Try it
- Repo: github.com/wrium/evasive-button
- Wrium: wrium.dev
It's MIT licensed, and the repo includes unit tests (Vitest) and end-to-end tests (Playwright). Issues and PRs are welcome. I'd love to see the creative ways you use it!
Top comments (0)