slide-accept

Slide-to-confirm interaction with drag handle, spring-back animation, keyboard support, and progressive enhancement.

Overview

The <slide-accept> component creates a slide-to-confirm interaction — a draggable handle that users slide across a track to confirm an action (like iOS “slide to power off”). If released early, the handle springs back. Once the threshold is reached, the component activates and fires a slide-accept:accept event.

<slide-accept data-label="Slide to confirm" data-activated-label="Confirmed!"> Slide to confirm </slide-accept>

Attributes

Attribute Type Default Description
data-label string "Slide to confirm" Track label text displayed inside the track.
data-activated-label string "Confirmed!" Label shown after activation.
data-attention string Attention animation: "shimmer" or "pulse".
data-threshold number 90 Activation threshold as a percentage (0–100).

Attention Animations

Shimmer

A sweeping shimmer effect draws attention to the track, encouraging interaction.

Slide to delete
<slide-accept data-label="Slide to delete" data-activated-label="Deleted!" data-attention="shimmer"> Slide to delete </slide-accept>

Pulse

A pulsing glow on the handle draws attention to the draggable element.

Slide to send
<slide-accept data-label="Slide to send" data-activated-label="Sent!" data-attention="pulse"> Slide to send </slide-accept>

Custom Threshold

By default, the handle must reach 90% of the track to activate. Set data-threshold to a lower value to make activation easier.

Slide halfway
<!-- Activate at 60% instead of default 90% --> <slide-accept data-label="Slide halfway" data-layout-threshold="60"> Slide halfway </slide-accept>

Keyboard Navigation

Key Action
ArrowRight Move handle 5%
Shift + ArrowRight Move handle 20%
ArrowLeft Move handle back 5%
End Activate immediately
Home Reset to start

Events

Event Description
slide-accept:accept Fired when the handle reaches the activation threshold.
slide-accept:reset Fired after reset() is called.
const slider = document.querySelector('slide-accept'); slider.addEventListener('slide-accept:accept', () => { console.log('Confirmed!'); }); slider.addEventListener('slide-accept:reset', () => { console.log('Reset'); });

Public API

Member Type Description
.activated getter Returns true if the component has been activated.
.reset() method Resets to initial state (handle at 0, label restored).
const slider = document.querySelector('slide-accept'); // Check state console.log(slider.activated); // true/false // Reset to initial state slider.reset();

Accessibility

Slider Role

The handle has role="slider" with aria-valuemin, aria-valuemax, and aria-valuenow. Screen readers announce position changes as the handle moves.

Keyboard Support

The handle is focusable (tabindex="0") and responds to arrow keys. Shift + arrow provides larger steps for faster navigation. End activates immediately, Home resets.

Reduced Motion

Spring-back animation and attention effects are disabled when prefers-reduced-motion: reduce is active.

Styling

The track, handle, and label are all styleable with CSS. The handle is a .slide-handle button, and the track is a .slide-track div.

/* Custom handle color */ slide-accept .slide-handle { background: oklch(55% 0.2 30); } /* Custom activated state */ slide-accept[data-activated] .slide-handle { background: oklch(50% 0.15 145); }

Progressive Enhancement

Without JavaScript, the element renders its text content as a readable pill-shaped element. The :not(:defined) selector provides the fallback. Once JS registers the component, the track and drag handle take over.

/* Without JS: renders as pill-shaped inline element */ slide-accept:not(:defined) { display: inline-flex; padding: var(--size-xs) var(--size-m); border-radius: var(--radius-pill); background: var(--color-surface-raised); }

Related Elements