Video Modal

A video thumbnail that morphs into a full accessible player inside a modal, with a custom keyboard-operable control bar.

Open in v0

Last updated: August 13, 2026

Installation

npx smoothui-cli add video-modal

Features

  • Thumbnail and modal frame share one layoutId, so opening reads as the same rectangle growing into place
  • Custom control bar: play/pause, a role="slider" scrub bar, mute, time display, fullscreen
  • Native controls fallback when showCustomControls is false
  • Optional <track> captions per language
  • Body scroll locks while open, video pauses on close and when the tab is hidden
  • Works controlled (open / onOpenChange) or uncontrolled
  • Composes Smooth Button for the play, mute, fullscreen and close controls

Accessibility

ARIA Attributes

AttributeElementPurpose
aria-modal="true"Modal panelMarks the panel as a modal dialog for assistive technology
role="dialog"Modal panelIdentifies the panel as a dialog
aria-labelModal panel, close button, play/pause, mute, fullscreenNames the dialog and every icon-only control
role="slider"Scrub barExposes the seek position as an adjustable range
aria-valuemin / aria-valuemax / aria-valuenow / aria-valuetextScrub barReports current playback position in seconds and as formatted text
aria-hidden="true"Closed-state thumbnail (while open)Hides the invisible morph source from assistive technology while the modal is open

Keyboard

KeyEffect
Enter / SpaceOpens the modal from the thumbnail
EscapeCloses the modal and returns focus to the thumbnail
Tab / Shift+TabCycles through the controls inside the modal; focus is trapped until it closes
/ on the scrub barSeeks 5 seconds backward or forward
Home / End on the scrub barJumps to the start or end of the video

Screen Reader

Opening the modal moves focus into the panel; closing it returns focus to the thumbnail that opened it. The thumbnail is marked aria-hidden and removed from the tab order while the modal is open, so a screen reader never announces the invisible morph source underneath it. Every icon-only button carries an aria-label that reflects its current state (Play/Pause, Mute/Unmute, Enter fullscreen/Exit fullscreen).

Reduced Motion

Uses useReducedMotion. When reduced motion is preferred: the shared layoutId morph is disabled (the modal simply appears), all transitions drop to duration: 0, and autoPlayOnOpen is ignored — the video never starts on its own.

Props

Created by

Powered by

motion.dev

© 2026 SmoothUI. Built by Eduardo Calvo.