Skip to content

feat(html): add <media-gesture> element#1305

Merged
mihar-22 merged 4 commits intomainfrom
feat/media-gesture-element
Apr 11, 2026
Merged

feat(html): add <media-gesture> element#1305
mihar-22 merged 4 commits intomainfrom
feat/media-gesture-element

Conversation

@mihar-22
Copy link
Copy Markdown
Member

@mihar-22 mihar-22 commented Apr 10, 2026

Closes #1273

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com


Note

Medium Risk
Introduces new gesture-action plumbing and new media state methods (togglePaused/toggleFullscreen/togglePictureInPicture) that become part of the public store/state surface, which could affect integrators and input handling across platforms.

Overview
Adds a new media-gesture custom element (exported from @videojs/html) that registers tap/double-tap gesture handlers on the player container and dispatches them to player/store actions via a new core resolveGestureAction helper.

Extends core media state with togglePaused, toggleFullscreen, and togglePictureInPicture, implements these toggles in the DOM store features (handling fullscreen/PiP mutual exclusion), and updates hotkey/PiP action naming from togglePiP to togglePictureInPicture across HTML/React skins and button components/tests.

Reviewed by Cursor Bugbot for commit 78bd7e7. Bugbot is set up for automated code reviews on this repo. Configure here.

Declarative gesture element that maps attributes to gesture factory
calls, mirroring `<media-hotkey>`. Supports `type` (tap/doubletap),
`action`, `value`, `pointer`, `region`, and `disabled` attributes.

Adds gesture action resolvers in core (`resolveGestureAction`) with
10 actions calling store methods directly via selectors. Shared by
both the HTML element and future React hooks.

Closes #1273

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 10, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
v10-sandbox Ready Ready Preview, Comment Apr 11, 2026 0:48am

Request Review

@netlify
Copy link
Copy Markdown

netlify bot commented Apr 10, 2026

Deploy Preview for vjs10-site ready!

Name Link
🔨 Latest commit 78bd7e7
🔍 Latest deploy log https://app.netlify.com/projects/vjs10-site/deploys/69d99a3cbfc2ef00082ed6af
😎 Deploy Preview https://deploy-preview-1305--vjs10-site.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 10, 2026

📦 Bundle Size Report

🎨 @videojs/html — no changes
Presets (7)
Entry Size
/video (default) 26.68 kB
/video (default + hls) 159.02 kB
/video (minimal) 25.00 kB
/video (minimal + hls) 157.35 kB
/audio (default) 24.72 kB
/audio (minimal) 23.17 kB
/background 4.16 kB
Media (8)
Entry Size
/media/background-video 1.04 kB
/media/container 1.73 kB
/media/dash-video 236.51 kB
/media/hls-video 133.61 kB
/media/mux-audio 156.14 kB
/media/mux-video 156.14 kB
/media/native-hls-video 3.62 kB
/media/simple-hls-video 15.87 kB
Players (3)
Entry Size
/video/player 6.41 kB
/audio/player 4.90 kB
/background/player 3.86 kB
Skins (17)
Entry Type Size
/video/minimal-skin.css css 3.47 kB
/video/skin.css css 3.49 kB
/video/minimal-skin js 24.99 kB
/video/minimal-skin.tailwind js 25.28 kB
/video/skin js 26.67 kB
/video/skin.tailwind js 26.86 kB
/audio/minimal-skin.css css 2.53 kB
/audio/skin.css css 2.50 kB
/audio/minimal-skin js 23.18 kB
/audio/minimal-skin.tailwind js 23.34 kB
/audio/skin js 24.74 kB
/audio/skin.tailwind js 24.89 kB
/background/skin.css css 117 B
/background/skin js 1.15 kB
/base.css css 157 B
/shared.css css 88 B
/skin-element js 1.35 kB
UI Components (23)
Entry Size
/ui/alert-dialog 995 B
/ui/alert-dialog-close 461 B
/ui/alert-dialog-description 389 B
/ui/alert-dialog-title 366 B
/ui/buffering-indicator 1.90 kB
/ui/captions-button 2.10 kB
/ui/controls 1.27 kB
/ui/error-dialog 2.40 kB
/ui/fullscreen-button 2.06 kB
/ui/hotkey 2.25 kB
/ui/mute-button 2.09 kB
/ui/pip-button 2.10 kB
/ui/play-button 2.25 kB
/ui/playback-rate-button 1.92 kB
/ui/popover 1.83 kB
/ui/poster 1.65 kB
/ui/seek-button 2.09 kB
/ui/slider 1.50 kB
/ui/thumbnail 2.36 kB
/ui/time 1.46 kB
/ui/time-slider 2.58 kB
/ui/tooltip 1.96 kB
/ui/volume-slider 2.15 kB

Sizes are marginal over the root entry point.

⚛️ @videojs/react — no changes
Presets (7)
Entry Size
/video (default) 21.45 kB
/video (default + hls) 153.93 kB
/video (minimal) 19.97 kB
/video (minimal + hls) 152.40 kB
/audio (default) 18.25 kB
/audio (minimal) 16.76 kB
/background 754 B
Media (7)
Entry Size
/media/background-video 575 B
/media/dash-video 236.42 kB
/media/hls-video 133.55 kB
/media/mux-audio 156.30 kB
/media/mux-video 156.29 kB
/media/native-hls-video 3.65 kB
/media/simple-hls-video 15.92 kB
Skins (14)
Entry Type Size
/video/minimal-skin.css css 3.40 kB
/video/skin.css css 3.42 kB
/video/minimal-skin js 19.90 kB
/video/minimal-skin.tailwind js 23.35 kB
/video/skin js 21.40 kB
/video/skin.tailwind js 23.42 kB
/audio/minimal-skin.css css 2.43 kB
/audio/skin.css css 2.39 kB
/audio/minimal-skin js 16.69 kB
/audio/minimal-skin.tailwind js 19.18 kB
/audio/skin js 18.19 kB
/audio/skin.tailwind js 19.17 kB
/background/skin.css css 90 B
/background/skin js 272 B
UI Components (19)
Entry Size
/ui/alert-dialog 1.11 kB
/ui/buffering-indicator 1.64 kB
/ui/captions-button 2.21 kB
/ui/controls 1.65 kB
/ui/error-dialog 1.57 kB
/ui/fullscreen-button 2.22 kB
/ui/mute-button 2.19 kB
/ui/pip-button 2.19 kB
/ui/play-button 2.19 kB
/ui/playback-rate-button 1.88 kB
/ui/popover 1.82 kB
/ui/poster 1.46 kB
/ui/seek-button 2.18 kB
/ui/slider 3.15 kB
/ui/thumbnail 1.94 kB
/ui/time 1.79 kB
/ui/time-slider 2.75 kB
/ui/tooltip 2.29 kB
/ui/volume-slider 2.86 kB

Sizes are marginal over the root entry point.

🧩 @videojs/core — no changes
Entries (8)
Entry Size
. 5.29 kB
/dom 11.27 kB
/dom/media/custom-media-element 1.91 kB
/dom/media/dash 235.94 kB
/dom/media/hls 132.95 kB
/dom/media/mux 155.69 kB
/dom/media/native-hls 2.97 kB
/dom/media/simple-hls 15.31 kB
🏷️ @videojs/element — no changes
Entries (2)
Entry Size
. 999 B
/context 943 B
📦 @videojs/store — no changes
Entries (3)
Entry Size
. 1.38 kB
/html 696 B
/react 360 B
🔧 @videojs/utils — no changes
Entries (10)
Entry Size
/array 104 B
/dom 1.74 kB
/events 319 B
/function 327 B
/object 247 B
/predicate 265 B
/string 148 B
/style 190 B
/time 478 B
/number 158 B
📦 @videojs/spf — no changes
Entries (3)
Entry Size
. 40 B
/dom 13.27 kB
/playback-engine 13.10 kB

ℹ️ How to interpret

All sizes are standalone totals (minified + brotli).

Icon Meaning
No change
🔺 Increased ≤ 10%
🔴 Increased > 10%
🔽 Decreased
🆕 New (no baseline)

Run pnpm size locally to check current sizes.

Add togglePaused, toggleFullscreen, and togglePiP methods to their
respective store features so gesture actions can call store methods
directly via store.state[action]() instead of reimplementing toggle
logic in an actions record.

Gesture resolveGestureAction now falls through to store.state[name]()
for direct store methods. Only seekStep, volumeStep, speedUp, and
speedDown use override resolvers for their custom logic.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rename the store method, action name, and all references across core,
html, and react packages for consistency with requestPictureInPicture
and exitPictureInPicture naming.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Accept GestureActionName | (string & {}) for autocomplete while
still allowing arbitrary strings from HTML attributes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mihar-22 mihar-22 marked this pull request as ready for review April 11, 2026 01:05
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 78bd7e7. Configure here.

const idx = playbackRates.indexOf(playbackRate);
const next = idx <= 0 ? playbackRates.length - 1 : idx - 1;
rate.setPlaybackRate(playbackRates[next]!);
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gesture action overrides duplicate hotkey action implementations

Medium Severity

The four GESTURE_ACTION_OVERRIDES (seekStep, volumeStep, speedUp, speedDown) are character-for-character identical copies of the same implementations in HOTKEY_ACTIONS in hotkey/actions.ts. Both only use store and value from their context (not key or event), so they could easily be extracted into shared utility functions that both gesture and hotkey resolvers reference.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 78bd7e7. Configure here.

@mihar-22 mihar-22 merged commit d2782f0 into main Apr 11, 2026
23 checks passed
@mihar-22 mihar-22 deleted the feat/media-gesture-element branch April 11, 2026 01:14
@luwes luwes mentioned this pull request Apr 11, 2026
This was referenced Apr 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: <media-gesture> Element

1 participant