Skip to content

feat(react)!: make thumbnail composable - #2566

Merged
mihar-22 merged 9 commits into
mainfrom
t3code/align-thumbnail-html-api
Sep 9, 2026
Merged

feat(react)!: make thumbnail composable#2566
mihar-22 merged 9 commits into
mainfrom
t3code/align-thumbnail-html-api

Conversation

@mihar-22

@mihar-22 mihar-22 commented Aug 31, 2026

Copy link
Copy Markdown
Member

Summary

Split the standalone React thumbnail into Thumbnail.Root and Thumbnail.Image. The root owns thumbnail selection, sizing, and state attributes, while the image owns native image props and the render escape hatch, making overlays and temporary presentation layers straightforward.

Changes

  • Replace standalone <Thumbnail /> usage with the compound Thumbnail.Root / Thumbnail.Image API
  • Keep Slider.Thumbnail as the existing convenience component, now composed from the new parts internally
  • Move image-specific CORS, loading, and fetch-priority props onto Thumbnail.Image
  • Share ThumbnailCore.resolveCrossOrigin between the HTML element and the React image
  • Rebind thumbnail load/error handling when a render override replaces the image node, keep the image ref stable across renders, and let connect() stay quiet when a settled image is handed back after a ref swap
  • Update React demos and reference guidance, using media-thumbnail-* class names
  • Define the Thumbnail component anatomy (Root, Image) in core so skins can compose a standalone thumbnail, type the nested Slider.Thumbnail parts from the same props, and map the standalone component in the HTML skin target
  • Fix the HTML skin target kebab-casing one-word attributes such as crossOrigin into cross-origin; crossorigin, fetchpriority, srcset, tabindex, and friends now emit their real names
Breaking change

React consumers migrate from <Thumbnail time={time} /> to <Thumbnail.Root time={time}><Thumbnail.Image /></Thumbnail.Root>. ThumbnailProps is replaced by ThumbnailRootProps and ThumbnailImageProps.

Testing

  • pnpm -F @videojs/core test src/dom/ui/tests/thumbnail.test.ts src/core/ui/thumbnail
  • pnpm -F @videojs/react test src/ui/thumbnail src/ui/slider/tests/slider-thumbnail.test.tsx
  • pnpm -F @videojs/html test src/ui/thumbnail src/ui/slider/tests/slider-thumbnail-element.test.ts
  • pnpm vp run @videojs/react#build
  • pnpm typecheck
  • pnpm lint

Note

Medium Risk
Breaking React public API and thumbnail/image lifecycle changes affect slider previews and CORS behavior; fixes are localized but consumer migration is required.

Overview
Breaking: React’s thumbnail is now a compound API (Thumbnail.Root + Thumbnail.Image) instead of a single <Thumbnail />. The root owns time, thumbnail resolution, sizing, and data-* state; the image owns crossOrigin, loading, fetchPriority, refs, and the render escape hatch so overlays can sit as siblings.

SliderThumbnail keeps the same external shape but is built from those parts internally and still injects pointer time. Core typings and vjsc component metadata are split to match (ThumbnailProps / ThumbnailImageProps, dedicated Thumbnail component definition, slider thumbnail omits time on the root part).

Shared ThumbnailCore.resolveCrossOrigin replaces duplicated logic in the HTML custom element; the DOM createThumbnail handle gains disconnectImg, per-image listener rebinding, and guards so cached images and React ref swaps do not re-fire state or cause render loops. Skins HTML target and htmlAttributeName aliases (e.g. crossOrigincrossorigin) are updated for the new anatomy; docs and demos migrate to Thumbnail.Root / Thumbnail.Image.

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

@vercel

vercel Bot commented Aug 31, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated
v10-sandbox Ready Ready Preview Sep 9, 2026 5:40am UTC

Request Review

@netlify

netlify Bot commented Aug 31, 2026

Copy link
Copy Markdown

Deploy Preview for vjs10-site ready!

Name Link
🔨 Latest commit 39c7c1f
🔍 Latest deploy log https://app.netlify.com/projects/vjs10-site/deploys/6aa0f118e06a55000842b916
😎 Deploy Preview https://deploy-preview-2566--vjs10-site.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

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

@pkg-pr-new

pkg-pr-new Bot commented Aug 31, 2026

Copy link
Copy Markdown
@videojs/cdn

pnpm add https://pkg.pr.new/@videojs/cdn@2566

@videojs/core

pnpm add https://pkg.pr.new/@videojs/core@2566

@videojs/element

pnpm add https://pkg.pr.new/@videojs/element@2566

@videojs/html

pnpm add https://pkg.pr.new/@videojs/html@2566

@videojs/media

pnpm add https://pkg.pr.new/@videojs/media@2566

@videojs/react

pnpm add https://pkg.pr.new/@videojs/react@2566

@videojs/spf

pnpm add https://pkg.pr.new/@videojs/spf@2566

@videojs/store

pnpm add https://pkg.pr.new/@videojs/store@2566

@videojs/utils

pnpm add https://pkg.pr.new/@videojs/utils@2566

@videojs/cloudflare-video

pnpm add https://pkg.pr.new/@videojs/cloudflare-video@2566

@videojs/dash-video

pnpm add https://pkg.pr.new/@videojs/dash-video@2566

@videojs/hlsjs-video

pnpm add https://pkg.pr.new/@videojs/hlsjs-video@2566

@videojs/mux-audio

pnpm add https://pkg.pr.new/@videojs/mux-audio@2566

@videojs/mux-video

pnpm add https://pkg.pr.new/@videojs/mux-video@2566

@videojs/native-hls-video

pnpm add https://pkg.pr.new/@videojs/native-hls-video@2566

@videojs/shaka-video

pnpm add https://pkg.pr.new/@videojs/shaka-video@2566

@videojs/spotify-audio

pnpm add https://pkg.pr.new/@videojs/spotify-audio@2566

@videojs/tiktok-video

pnpm add https://pkg.pr.new/@videojs/tiktok-video@2566

@videojs/twitch-video

pnpm add https://pkg.pr.new/@videojs/twitch-video@2566

@videojs/vimeo-video

pnpm add https://pkg.pr.new/@videojs/vimeo-video@2566

@videojs/wistia-video

pnpm add https://pkg.pr.new/@videojs/wistia-video@2566

@videojs/youtube-video

pnpm add https://pkg.pr.new/@videojs/youtube-video@2566

@videojs/google-cast

pnpm add https://pkg.pr.new/@videojs/google-cast@2566

@videojs/mux-data

pnpm add https://pkg.pr.new/@videojs/mux-data@2566

commit: 39c7c1f

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Size Report

🎨 @videojs/html

Path Base initial PR initial Initial diff Lazy diff
/video/minimal-skin 61.46 kB 61.82 kB +374 B (+0.6%) 0 B
/video (minimal + hls) 64.77 kB 65.09 kB +334 B (+0.5%) 0 B
Small changes (69, ≤ 300 B)
Path Base initial PR initial Initial diff Lazy diff
/video/minimal-skin.css 7.65 kB 7.71 kB +56 B (+0.7%)
/video/skin.css 7.46 kB 7.53 kB +66 B (+0.9%)
/video/minimal-skin2 8.09 kB 8.17 kB +81 B (+1.0%)
/video/player 9.69 kB 9.70 kB +13 B (+0.1%) 0 B
/video/skin 61.34 kB 61.59 kB +255 B (+0.4%) 0 B
/video/skin2 7.95 kB 8.02 kB +71 B (+0.9%)
/audio/minimal-skin.css 5.53 kB 5.58 kB +57 B (+1.0%)
/audio/skin.css 5.34 kB 5.41 kB +66 B (+1.2%)
/audio/minimal-skin 45.77 kB 45.89 kB +120 B (+0.3%) 0 B
/audio/minimal-skin2 5.83 kB 5.90 kB +63 B (+1.1%)
/audio/player 6.14 kB 6.16 kB +19 B (+0.3%) 0 B
/audio/skin 45.50 kB 45.63 kB +140 B (+0.3%) 0 B
/audio/skin2 5.65 kB 5.73 kB +84 B (+1.5%)
/background/skin 9.81 kB 9.82 kB +18 B (+0.2%) 0 B
/live-video/minimal-skin.css 6.21 kB 6.24 kB +28 B (+0.4%)
/live-video/skin.css 6.18 kB 6.22 kB +41 B (+0.6%)
/live-video/minimal-skin 49.42 kB 49.58 kB +170 B (+0.3%) 0 B
/live-video/minimal-skin2 6.55 kB 6.58 kB +32 B (+0.5%)
/live-video/player 9.06 kB 9.08 kB +15 B (+0.2%) 0 B
/live-video/skin 49.43 kB 49.67 kB +243 B (+0.5%) 0 B
/live-video/skin2 6.58 kB 6.63 kB +41 B (+0.6%)
/live-audio/minimal-skin.css 4.39 kB 4.45 kB +59 B (+1.3%)
/live-audio/skin.css 4.37 kB 4.44 kB +77 B (+1.7%)
/live-audio/minimal-skin 35.43 kB 35.53 kB +99 B (+0.3%) 0 B
/live-audio/minimal-skin2 4.64 kB 4.71 kB +63 B (+1.3%)
/live-audio/player 6.15 kB 6.16 kB +11 B (+0.2%) 0 B
/live-audio/skin 35.36 kB 35.51 kB +155 B (+0.4%) 0 B
/live-audio/skin2 4.63 kB 4.71 kB +82 B (+1.7%)
/ui/airplay-button 11.26 kB 11.27 kB +11 B (+0.1%) 0 B
/ui/audio-track-radio-group 11.38 kB 11.39 kB +18 B (+0.2%) 0 B
/ui/buffering-indicator 8.60 kB 8.62 kB +24 B (+0.3%) 0 B
/ui/captions-button 11.51 kB 11.52 kB +7 B (+0.1%) 0 B
/ui/captions-radio-group 11.45 kB 11.48 kB +23 B (+0.2%) 0 B
/ui/cast-button 11.25 kB 11.25 kB +10 B (+0.1%) 0 B
/ui/container 9.47 kB 9.48 kB +9 B (+0.1%) 0 B
/ui/controls 8.77 kB 8.79 kB +19 B (+0.2%) 0 B
/ui/error-dialog 12.38 kB 12.41 kB +24 B (+0.2%) 0 B
/ui/fullscreen-button 11.26 kB 11.27 kB +11 B (+0.1%) 0 B
/ui/gesture 9.57 kB 9.60 kB +33 B (+0.3%) 0 B
/ui/hotkey 9.97 kB 9.99 kB +17 B (+0.2%) 0 B
/ui/live-button 9.74 kB 9.76 kB +18 B (+0.2%) 0 B
/ui/menu 18.45 kB 18.47 kB +16 B (+0.1%) 0 B
/ui/mute-button 11.28 kB 11.28 kB +1 B (+0.0%) 0 B
/ui/pip-button 11.22 kB 11.23 kB +6 B (+0.1%) 0 B
/ui/play-button 11.22 kB 11.23 kB +14 B (+0.1%) 0 B
/ui/playback-rate-button 11.32 kB 11.33 kB +8 B (+0.1%) 0 B
/ui/playback-rate-radio-group 11.38 kB 11.39 kB +12 B (+0.1%) 0 B
/ui/poster 8.67 kB 8.90 kB +230 B (+2.6%) 0 B
/ui/quality-radio-group 11.97 kB 11.98 kB +6 B (+0.0%) 0 B
/ui/seek-button 11.27 kB 11.26 kB -12 B (-0.1%) 0 B
/ui/seek-indicator 12.69 kB 12.69 kB +5 B (+0.0%) 0 B
/ui/slider 11.65 kB 11.68 kB +32 B (+0.3%) 0 B
/ui/status-announcer 10.60 kB 10.61 kB +9 B (+0.1%) 0 B
/ui/status-indicator 13.01 kB 13.04 kB +22 B (+0.2%) 0 B
/ui/thumbnail 9.84 kB 9.95 kB +116 B (+1.2%) 0 B
/ui/time 10.80 kB 10.81 kB +3 B (+0.0%) 0 B
/ui/time-slider 12.99 kB 13.02 kB +22 B (+0.2%) 0 B
/ui/time-slider-chapter-title 8.79 kB 8.81 kB +23 B (+0.3%) 0 B
/ui/time-slider-chapters 9.63 kB 9.64 kB +9 B (+0.1%) 0 B
/ui/title 8.17 kB 8.18 kB +16 B (+0.2%) 0 B
/ui/volume-indicator 13.02 kB 13.03 kB +9 B (+0.1%) 0 B
/ui/volume-popover 14.74 kB 14.75 kB +12 B (+0.1%) 0 B
/ui/volume-slider 12.31 kB 12.36 kB +48 B (+0.4%) 0 B
/video (default) 62.79 kB 62.97 kB +188 B (+0.3%) 0 B
/video (default + hls) 64.52 kB 64.78 kB +267 B (+0.4%) 0 B
/video (minimal) 63.04 kB 63.29 kB +260 B (+0.4%) 0 B
/audio (default) 46.99 kB 47.09 kB +103 B (+0.2%) 0 B
/audio (minimal) 47.21 kB 47.31 kB +112 B (+0.2%) 0 B
/background 11.57 kB 11.59 kB +21 B (+0.2%) 0 B
Presets (7)
Entry Initial Lazy
/video (default) 62.97 kB 56.87 kB
/video (default + hls) 64.78 kB 56.87 kB
/video (minimal) 63.29 kB 56.87 kB
/video (minimal + hls) 65.09 kB 56.87 kB
/audio (default) 47.09 kB 56.87 kB
/audio (minimal) 47.31 kB 56.87 kB
/background 11.59 kB 56.87 kB
Media (18)
Entry Initial
/media/mux-video 3.02 kB
/media/mux-audio 2.69 kB
/media/background-video 1.16 kB
/media/cloudflare-video 2.90 kB
/media/dash-video 2.63 kB
/media/hls-audio 22.05 kB
/media/hls-background-video 16.86 kB
/media/hls-video 28.00 kB
/media/hlsjs-video 2.63 kB
/media/mux-background-video 16.86 kB
/media/native-hls-video 7.57 kB
/media/shaka-video 2.63 kB
/media/spotify-audio 3.02 kB
/media/tiktok-video 3.13 kB
/media/twitch-video 2.93 kB
/media/vimeo-video 2.90 kB
/media/wistia-video 607 B
/media/youtube-video 2.90 kB
Players (5)
Entry Initial Lazy
/video/player 9.70 kB 56.87 kB
/audio/player 6.16 kB 56.87 kB
/background/player 4.46 kB 56.87 kB
/live-video/player 9.08 kB 56.87 kB
/live-audio/player 6.16 kB 56.87 kB
Skins (29)
Entry Type Initial Lazy
/video/minimal-skin.css css 7.71 kB
/video/skin.css css 7.53 kB
/video/minimal-skin js 61.82 kB 56.87 kB
/video/minimal-skin2 js 8.17 kB
/video/skin js 61.59 kB 56.87 kB
/video/skin2 js 8.02 kB
/audio/minimal-skin.css css 5.58 kB
/audio/skin.css css 5.41 kB
/audio/minimal-skin js 45.89 kB 56.87 kB
/audio/minimal-skin2 js 5.90 kB
/audio/skin js 45.63 kB 56.87 kB
/audio/skin2 js 5.73 kB
/background/skin.css css 139 B
/background/skin js 9.82 kB 56.87 kB
/background/skin2 js 187 B
/live-video/minimal-skin.css css 6.24 kB
/live-video/skin.css css 6.22 kB
/live-video/minimal-skin js 49.58 kB 56.87 kB
/live-video/minimal-skin2 js 6.58 kB
/live-video/skin js 49.67 kB 56.87 kB
/live-video/skin2 js 6.63 kB
/live-audio/minimal-skin.css css 4.45 kB
/live-audio/skin.css css 4.44 kB
/live-audio/minimal-skin js 35.53 kB 56.87 kB
/live-audio/minimal-skin2 js 4.71 kB
/live-audio/skin js 35.51 kB 56.87 kB
/live-audio/skin2 js 4.71 kB
/global.css css 190 B
/shared.css css 118 B
UI Components (62)
Entry Initial Lazy
/ui/airplay-button 11.27 kB 56.87 kB
/ui/alert-dialog 8.79 kB 56.87 kB
/ui/audio-track-radio-group 11.39 kB 56.87 kB
/ui/buffering-indicator 8.62 kB 56.87 kB
/ui/captions-button 11.52 kB 56.87 kB
/ui/captions-radio-group 11.48 kB 56.87 kB
/ui/cast-button 11.25 kB 56.87 kB
/ui/container 9.48 kB 56.87 kB
/ui/controls 8.79 kB 56.87 kB
/ui/controls-backdrop 1.69 kB 56.87 kB
/ui/controls-content 1.67 kB 56.87 kB
/ui/dialog 8.73 kB 56.87 kB
/ui/dialog-backdrop 1.70 kB 56.87 kB
/ui/dialog-close 2.06 kB 56.87 kB
/ui/dialog-description 1.69 kB 56.87 kB
/ui/dialog-popup 1.90 kB 56.87 kB
/ui/dialog-title 1.70 kB 56.87 kB
/ui/error-dialog 12.41 kB 56.87 kB
/ui/fullscreen-button 11.27 kB 56.87 kB
/ui/gesture 9.60 kB 56.87 kB
/ui/hotkey 9.99 kB 56.87 kB
/ui/live-button 9.76 kB 56.87 kB
/ui/menu 18.47 kB 56.87 kB
/ui/menu-checkbox-item 1.97 kB 56.87 kB
/ui/menu-content 7.52 kB 56.87 kB
/ui/menu-group 2.09 kB 56.87 kB
/ui/menu-group-label 1.64 kB
/ui/menu-item 2.29 kB 56.87 kB
/ui/menu-item-indicator 1.37 kB 56.87 kB
/ui/menu-radio-group 3.01 kB 56.87 kB
/ui/menu-radio-item 2.13 kB 56.87 kB
/ui/menu-separator 1.30 kB 56.87 kB
/ui/mute-button 11.28 kB 56.87 kB
/ui/pip-button 11.23 kB 56.87 kB
/ui/play-button 11.23 kB 56.87 kB
/ui/playback-rate-button 11.33 kB 56.87 kB
/ui/playback-rate-radio-group 11.39 kB 56.87 kB
/ui/popover 8.57 kB 56.87 kB
/ui/poster 8.90 kB 56.87 kB
/ui/quality-radio-group 11.98 kB 56.87 kB
/ui/seek-button 11.26 kB 56.87 kB
/ui/seek-indicator 12.69 kB 56.87 kB
/ui/seek-indicator-value 1.10 kB
/ui/slider 11.68 kB 56.87 kB
/ui/slider-preview 2.01 kB 56.87 kB
/ui/status-announcer 10.61 kB 56.87 kB
/ui/status-indicator 13.04 kB 56.87 kB
/ui/status-indicator-value 1.10 kB
/ui/thumbnail 9.95 kB 56.87 kB
/ui/time 10.81 kB 56.87 kB
/ui/time-slider 13.02 kB 56.87 kB
/ui/time-slider-chapter-title 8.81 kB 56.87 kB
/ui/time-slider-chapters 9.64 kB 56.87 kB
/ui/title 8.18 kB 56.87 kB
/ui/tooltip 9.95 kB 56.87 kB
/ui/tooltip-label 1.21 kB
/ui/tooltip-shortcut 1.18 kB
/ui/volume-indicator 13.03 kB 56.87 kB
/ui/volume-indicator-fill 1.11 kB
/ui/volume-indicator-value 1.10 kB
/ui/volume-popover 14.75 kB 56.87 kB
/ui/volume-slider 12.36 kB 56.87 kB

⚛️ @videojs/react

Path Base initial PR initial Initial diff Lazy diff
/video/minimal-skin 50.63 kB 51.17 kB +554 B (+1.1%) 0 B
/video/skin 50.50 kB 50.99 kB +493 B (+1.0%) 0 B
/ui/poster 7.57 kB 7.89 kB +333 B (+4.3%) 0 B
/ui/slider 12.74 kB 13.05 kB +319 B (+2.4%) 0 B
/ui/thumbnail 8.73 kB 9.13 kB +415 B (+4.6%) 0 B
/video (default) 50.61 kB 51.08 kB +485 B (+0.9%) 0 B
/video (default + hls) 50.83 kB 51.38 kB +557 B (+1.1%) 0 B
/video (minimal) 50.66 kB 51.29 kB +639 B (+1.2%) 0 B
/video (minimal + hls) 51.06 kB 51.53 kB +478 B (+0.9%) 0 B
Small changes (52, ≤ 300 B)
Path Base initial PR initial Initial diff Lazy diff
/video/minimal-skin.css 7.52 kB 7.56 kB +42 B (+0.5%)
/video/skin.css 7.34 kB 7.37 kB +39 B (+0.5%)
/video/player 7.56 kB 7.58 kB +14 B (+0.2%) 0 B
/audio/minimal-skin.css 5.37 kB 5.39 kB +18 B (+0.3%)
/audio/skin.css 5.18 kB 5.23 kB +45 B (+0.8%)
/audio/minimal-skin 39.46 kB 39.51 kB +49 B (+0.1%) 0 B
/audio/player 4.00 kB 4.01 kB +13 B (+0.3%) 0 B
/audio/skin 39.40 kB 39.46 kB +60 B (+0.1%) 0 B
/live-video/minimal-skin.css 6.07 kB 6.09 kB +16 B (+0.3%)
/live-video/skin.css 6.05 kB 6.07 kB +20 B (+0.3%)
/live-video/minimal-skin 42.57 kB 42.78 kB +222 B (+0.5%) 0 B
/live-video/player 6.95 kB 6.97 kB +18 B (+0.3%) 0 B
/live-video/skin 42.52 kB 42.72 kB +209 B (+0.5%) 0 B
/live-audio/minimal-skin.css 4.24 kB 4.26 kB +23 B (+0.5%)
/live-audio/skin.css 4.21 kB 4.26 kB +43 B (+1.0%)
/live-audio/minimal-skin 30.35 kB 30.41 kB +55 B (+0.2%) 0 B
/live-audio/player 3.99 kB 4.01 kB +15 B (+0.4%) 0 B
/live-audio/skin 30.36 kB 30.42 kB +56 B (+0.2%) 0 B
/ui/airplay-button 10.45 kB 10.46 kB +12 B (+0.1%) 0 B
/ui/audio-track 7.92 kB 7.95 kB +21 B (+0.3%) 0 B
/ui/audio-track-radio-group 9.48 kB 9.50 kB +19 B (+0.2%) 0 B
/ui/buffering-indicator 7.79 kB 7.82 kB +27 B (+0.3%) 0 B
/ui/captions-button 10.43 kB 10.45 kB +13 B (+0.1%) 0 B
/ui/captions-radio-group 9.59 kB 9.61 kB +14 B (+0.1%) 0 B
/ui/cast-button 10.43 kB 10.45 kB +14 B (+0.1%) 0 B
/ui/controls 7.71 kB 7.72 kB +10 B (+0.1%) 0 B
/ui/error-dialog 11.80 kB 11.81 kB +15 B (+0.1%) 0 B
/ui/fullscreen-button 10.39 kB 10.42 kB +31 B (+0.3%) 0 B
/ui/gesture 7.98 kB 8.00 kB +21 B (+0.3%) 0 B
/ui/hotkey 8.38 kB 8.39 kB +20 B (+0.2%) 0 B
/ui/live-button 8.80 kB 8.81 kB +13 B (+0.1%) 0 B
/ui/menu 19.45 kB 19.48 kB +37 B (+0.2%) 0 B
/ui/mute-button 10.44 kB 10.46 kB +21 B (+0.2%) 0 B
/ui/pip-button 10.39 kB 10.41 kB +13 B (+0.1%) 0 B
/ui/play-button 10.37 kB 10.39 kB +19 B (+0.2%) 0 B
/ui/playback-rate 7.99 kB 7.99 kB +5 B (+0.1%) 0 B
/ui/playback-rate-button 10.37 kB 10.38 kB +16 B (+0.2%) 0 B
/ui/playback-rate-radio-group 9.53 kB 9.55 kB +19 B (+0.2%) 0 B
/ui/quality 8.42 kB 8.44 kB +14 B (+0.2%) 0 B
/ui/quality-radio-group 9.96 kB 9.98 kB +26 B (+0.3%) 0 B
/ui/seek-button 10.41 kB 10.43 kB +16 B (+0.2%) 0 B
/ui/seek-indicator 11.98 kB 11.99 kB +15 B (+0.1%) 0 B
/ui/status-announcer 10.10 kB 10.11 kB +17 B (+0.2%) 0 B
/ui/status-indicator 12.29 kB 12.30 kB +15 B (+0.1%) 0 B
/ui/time 9.77 kB 9.79 kB +25 B (+0.3%) 0 B
/ui/time-slider 14.17 kB 14.22 kB +51 B (+0.4%) 0 B
/ui/title 7.28 kB 7.29 kB +11 B (+0.1%) 0 B
/ui/volume-indicator 12.34 kB 12.35 kB +17 B (+0.1%) 0 B
/ui/volume-popover 14.20 kB 14.22 kB +18 B (+0.1%) 0 B
/ui/volume-slider 12.13 kB 12.18 kB +52 B (+0.4%) 0 B
/audio (default) 39.50 kB 39.53 kB +31 B (+0.1%) 0 B
/audio (minimal) 39.56 kB 39.61 kB +56 B (+0.1%) 0 B
Presets (7)
Entry Initial Lazy
/video (default) 51.08 kB 56.87 kB
/video (default + hls) 51.38 kB 56.87 kB
/video (minimal) 51.29 kB 56.87 kB
/video (minimal + hls) 51.53 kB 56.87 kB
/audio (default) 39.53 kB 56.87 kB
/audio (minimal) 39.61 kB 56.87 kB
/background 581 B 56.87 kB
Media (22)
Entry Initial
/media/mux-video/hls-js 958 B
/media/mux-video/spf 961 B
/media/mux-audio/hls-js 699 B
/media/mux-audio/spf 703 B
/media/background-video 402 B
/media/cloudflare-video 911 B
/media/dash-video 693 B
/media/hls-audio 20.36 kB
/media/hls-background-video 16.40 kB
/media/hls-video 26.35 kB
/media/hlsjs-video 695 B
/media/mux-audio 693 B
/media/mux-background-video 16.47 kB
/media/mux-video 950 B
/media/native-hls-video 5.77 kB
/media/shaka-video 704 B
/media/spotify-audio 901 B
/media/tiktok-video 906 B
/media/twitch-video 929 B
/media/vimeo-video 888 B
/media/wistia-video 619 B
/media/youtube-video 897 B
Extensions (2)
Entry Initial
/extensions/google-cast 1.59 kB
/extensions/mux-data 1.64 kB
Players (5)
Entry Initial Lazy
/video/player 7.58 kB 56.87 kB
/audio/player 4.01 kB 56.87 kB
/background/player 2.27 kB 56.87 kB
/live-video/player 6.97 kB 56.87 kB
/live-audio/player 4.01 kB 56.87 kB
Skins (18)
Entry Type Initial Lazy
/video/minimal-skin.css css 7.56 kB
/video/skin.css css 7.37 kB
/video/minimal-skin js 51.17 kB 56.87 kB
/video/skin js 50.99 kB 56.87 kB
/audio/minimal-skin.css css 5.39 kB
/audio/skin.css css 5.23 kB
/audio/minimal-skin js 39.51 kB 56.87 kB
/audio/skin js 39.46 kB 56.87 kB
/background/skin.css css 90 B
/background/skin js 277 B
/live-video/minimal-skin.css css 6.09 kB
/live-video/skin.css css 6.07 kB
/live-video/minimal-skin js 42.78 kB 56.87 kB
/live-video/skin js 42.72 kB 56.87 kB
/live-audio/minimal-skin.css css 4.26 kB
/live-audio/skin.css css 4.26 kB
/live-audio/minimal-skin js 30.41 kB 56.87 kB
/live-audio/skin js 30.42 kB 56.87 kB
UI Components (39)
Entry Initial Lazy
/ui/airplay-button 10.46 kB 56.87 kB
/ui/alert-dialog 4.73 kB 56.87 kB
/ui/audio-track 7.95 kB 56.87 kB
/ui/audio-track-radio-group 9.50 kB 56.87 kB
/ui/buffering-indicator 7.82 kB 56.87 kB
/ui/captions-button 10.45 kB 56.87 kB
/ui/captions-radio-group 9.61 kB 56.87 kB
/ui/cast-button 10.45 kB 56.87 kB
/ui/controls 7.72 kB 56.87 kB
/ui/dialog 4.75 kB 56.87 kB
/ui/error-dialog 11.81 kB 56.87 kB
/ui/fullscreen-button 10.42 kB 56.87 kB
/ui/gesture 8.00 kB 56.87 kB
/ui/hotkey 8.39 kB 56.87 kB
/ui/live-button 8.81 kB 56.87 kB
/ui/menu 19.48 kB 56.87 kB
/ui/mute-button 10.46 kB 56.87 kB
/ui/pip-button 10.41 kB 56.87 kB
/ui/play-button 10.39 kB 56.87 kB
/ui/playback-rate 7.99 kB 56.87 kB
/ui/playback-rate-button 10.38 kB 56.87 kB
/ui/playback-rate-radio-group 9.55 kB 56.87 kB
/ui/popover 8.16 kB 56.87 kB
/ui/poster 7.89 kB 56.87 kB
/ui/quality 8.44 kB 56.87 kB
/ui/quality-radio-group 9.98 kB 56.87 kB
/ui/seek-button 10.43 kB 56.87 kB
/ui/seek-indicator 11.99 kB 56.87 kB
/ui/slider 13.05 kB 56.87 kB
/ui/status-announcer 10.11 kB 56.87 kB
/ui/status-indicator 12.30 kB 56.87 kB
/ui/thumbnail 9.13 kB 56.87 kB
/ui/time 9.79 kB 56.87 kB
/ui/time-slider 14.22 kB 56.87 kB
/ui/title 7.29 kB 56.87 kB
/ui/tooltip 8.93 kB 56.87 kB
/ui/volume-indicator 12.35 kB 56.87 kB
/ui/volume-popover 14.22 kB 56.87 kB
/ui/volume-slider 12.18 kB 56.87 kB
🧩 @videojs/core — 3 small size changes
Path Base initial PR initial Initial diff Lazy diff
. 13.15 kB 13.20 kB +47 B (+0.3%)
/dom 22.53 kB 22.67 kB +140 B (+0.6%) 0 B
/vjsc 1.82 kB 1.85 kB +33 B (+1.8%)
Entries (76)
Entry Initial Lazy
. 13.20 kB
/dom 22.67 kB 56.87 kB
/vjsc 1.85 kB
/i18n 3.23 kB 56.87 kB
/i18n/locales/all 34.97 kB
/i18n/locales/ar 1.22 kB
/i18n/locales/az 1.09 kB
/i18n/locales/bg 1.29 kB
/i18n/locales/bn 1.23 kB
/i18n/locales/bs 1.00 kB
/i18n/locales/ca 1.07 kB
/i18n/locales/cs 1.07 kB
/i18n/locales/cy 1.02 kB
/i18n/locales/da 1006 B
/i18n/locales/de 1.09 kB
/i18n/locales/el 1.49 kB
/i18n/locales/en 785 B
/i18n/locales/es 1018 B
/i18n/locales/et 1.05 kB
/i18n/locales/eu 1.03 kB
/i18n/locales/fa 1.22 kB
/i18n/locales/fi 1.04 kB
/i18n/locales/fr 1.07 kB
/i18n/locales/gd 1.10 kB
/i18n/locales/gl 1022 B
/i18n/locales/he 1.14 kB
/i18n/locales/hi 1.30 kB
/i18n/locales/hr 1.02 kB
/i18n/locales/hu 1.10 kB
/i18n/locales/id 919 B
/i18n/locales/it 1.01 kB
/i18n/locales/ja 1.18 kB
/i18n/locales/ko 1.14 kB
/i18n/locales/lt 1.02 kB
/i18n/locales/lv 1.09 kB
/i18n/locales/mr 1.30 kB
/i18n/locales/nb 987 B
/i18n/locales/ne 1.29 kB
/i18n/locales/nl 1.00 kB
/i18n/locales/nn 987 B
/i18n/locales/oc 1.08 kB
/i18n/locales/pl 1.14 kB
/i18n/locales/pt 1.03 kB
/i18n/locales/pt-BR 1.03 kB
/i18n/locales/pt-PT 1.01 kB
/i18n/locales/ro 1.07 kB
/i18n/locales/ru 1.40 kB
/i18n/locales/sk 1.10 kB
/i18n/locales/sl 1.04 kB
/i18n/locales/sr 1.07 kB
/i18n/locales/sv 1.01 kB
/i18n/locales/te 1.32 kB
/i18n/locales/th 1.29 kB
/i18n/locales/tr 1.08 kB
/i18n/locales/uk 1.41 kB
/i18n/locales/vi 1.11 kB
/i18n/locales/zh 1.02 kB
/i18n/locales/zh-CN 1.02 kB
/i18n/locales/zh-TW 1.02 kB
/i18n/text/airplay 101 B
/i18n/text/buttons 137 B
/i18n/text/captions 93 B
/i18n/text/cast 114 B
/i18n/text/common 90 B
/i18n/text/container 75 B
/i18n/text/errors 285 B
/i18n/text/fullscreen 98 B
/i18n/text/live 126 B
/i18n/text/menu 249 B
/i18n/text/pip 101 B
/i18n/text/playback 80 B
/i18n/text/seek 105 B
/i18n/text/slider 65 B
/i18n/text/status 222 B
/i18n/text/time 280 B
/i18n/text/volume 133 B
🏷️ @videojs/element — no changes
Entries (2)
Entry Initial
. 1.05 kB
/context 943 B
📦 @videojs/store — no changes
Entries (3)
Entry Initial
. 1.72 kB
/html 703 B
/react 365 B
🔧 @videojs/utils — no changes
Entries (13)
Entry Initial
/array 271 B
/dom 5.02 kB
/events 320 B
/function 386 B
/i18n 249 B
/jwt 176 B
/object 535 B
/predicate 297 B
/percent 281 B
/string 239 B
/style 212 B
/time 976 B
/number 199 B
📦 @videojs/cdn — 1 small size change
Path Base initial PR initial Initial diff Lazy diff
/package.json 818 B 810 B -8 B (-1.0%)
📦 @videojs/cloudflare-video — no changes
📦 @videojs/dash-video — no changes
📦 @videojs/google-cast — no changes
📦 @videojs/hlsjs-video — no changes
📦 @videojs/media — no changes
Entries (3)
Entry Initial
. 1.14 kB
/dom 4.12 kB
/media-tracks 2.05 kB
📦 @videojs/mux — no changes
📦 @videojs/mux-audio — no changes
Entries (2)
Entry Initial
. 135.58 kB
/spf 20.84 kB
📦 @videojs/mux-data — 1 small size change
Path Base initial PR initial Initial diff Lazy diff
. 24.33 kB 24.34 kB +4 B (+0.0%)
📦 @videojs/mux-video — no changes
Entries (2)
Entry Initial
. 135.56 kB
/spf 26.75 kB
📦 @videojs/native-hls-video — no changes
📦 @videojs/shaka-video — no changes
📦 @videojs/spf — no changes
Entries (7)
Entry Initial
. 4.55 kB
/dom 6.60 kB
/hls 22.06 kB
/media-tracks 504 B
/hls-background-video 15.84 kB
/hls-audio 19.84 kB
/hls-video 25.89 kB
📦 @videojs/spotify-audio — no changes
📦 @videojs/tiktok-video — no changes
📦 @videojs/twitch-video — no changes
📦 @videojs/vimeo-video — no changes
📦 @videojs/wistia-video — no changes
Entries (2)
Entry Initial
. 1.91 kB
/helpers 1.77 kB
📦 @videojs/youtube-video — no changes

ℹ️ How to interpret

Each entry is independently bundled, minified, and brotli-compressed. Initial size includes its static import graph; lazy dynamic chunks are reported separately.

Entries are not additive because their dependency graphs overlap. Preset rows represent realistic combined bundles.

Changes of 300 B or less across initial, lazy, and total size are collapsed, not discarded.

Run pnpm size locally to check current initial sizes.

Comment thread packages/react/src/ui/thumbnail/thumbnail-image.tsx Outdated
Comment thread packages/react/src/ui/thumbnail/thumbnail-root.tsx

@luwes luwes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM! I suppose the inherited cross origin logic will be removed in the future, the text track hooks in the image components look awkward seeing that again.

Comment thread site/src/content/docs/reference/thumbnail.mdx
Comment thread packages/react/src/ui/thumbnail/thumbnail-root.tsx

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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 using default effort 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 ef89016. Configure here.

Comment thread packages/react/src/ui/slider/slider-thumbnail.tsx
mihar-22 and others added 6 commits September 3, 2026 16:48
Match the Slider.Thumbnail.Image part name already used by the VJSC schema
so every image part reads *.Image.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Move the crossorigin resolution rule onto ThumbnailCore so the HTML element
and React image share it, and replace the React context's ref plus
connect/disconnect callbacks with a single callback ref owned by the root.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Compose the forwarded ref with the root's image ref once, so React no longer
detaches and reattaches the image on every render. When a renderer does hand the
same settled image back, `connect()` now only notifies when the checked state
actually changed, which stops the render loop Bugbot reported.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The convenience component accepted root children through its props type but
its JSX child replaced them, so overlays never mounted.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@mihar-22
mihar-22 force-pushed the t3code/align-thumbnail-html-api branch from 30a205f to 12b5cb1 Compare September 3, 2026 23:48
@netlify

netlify Bot commented Sep 3, 2026

Copy link
Copy Markdown

Deploy Preview for vjs-registry ready!

Name Link
🔨 Latest commit 39c7c1f
🔍 Latest deploy log https://app.netlify.com/projects/vjs-registry/deploys/6aa0f118e06a55000842b91a
😎 Deploy Preview https://deploy-preview-2566--vjs-registry.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

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

Give the standalone thumbnail a VJSC definition with Root and Image parts, type the nested
Slider.Thumbnail parts from the same props, and map the standalone component in the HTML skin
target. The HTML target also gains lowercase aliases for one-word HTML attributes such as
crossorigin and fetchpriority, which the kebab-case fallback misspelled.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@mihar-22
mihar-22 merged commit 55b36ab into main Sep 9, 2026
60 of 62 checks passed
@mihar-22
mihar-22 deleted the t3code/align-thumbnail-html-api branch September 9, 2026 05:42
@videojs-release videojs-release Bot mentioned this pull request Sep 9, 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.

2 participants