feat(react)!: make thumbnail composable - #2566
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
✅ Deploy Preview for vjs10-site ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
@videojs/cdn
@videojs/core
@videojs/element
@videojs/html
@videojs/media
@videojs/react
@videojs/spf
@videojs/store
@videojs/utils
@videojs/cloudflare-video
@videojs/dash-video
@videojs/hlsjs-video
@videojs/mux-audio
@videojs/mux-video
@videojs/native-hls-video
@videojs/shaka-video
@videojs/spotify-audio
@videojs/tiktok-video
@videojs/twitch-video
@videojs/vimeo-video
@videojs/wistia-video
@videojs/youtube-video
@videojs/google-cast
@videojs/mux-data
commit: |
📦 Bundle Size Report🎨 @videojs/html
Small changes (69, ≤ 300 B)
Presets (7)
Media (18)
Players (5)
Skins (29)
UI Components (62)
⚛️ @videojs/react
Small changes (52, ≤ 300 B)
Presets (7)
Media (22)
Extensions (2)
Players (5)
Skins (18)
UI Components (39)
🧩 @videojs/core — 3 small size changes
Entries (76)
🏷️ @videojs/element — no changesEntries (2)
📦 @videojs/store — no changesEntries (3)
🔧 @videojs/utils — no changesEntries (13)
📦 @videojs/cdn — 1 small size change
📦 @videojs/cloudflare-video — no changes📦 @videojs/dash-video — no changes📦 @videojs/google-cast — no changes📦 @videojs/hlsjs-video — no changes📦 @videojs/media — no changesEntries (3)
📦 @videojs/mux — no changes📦 @videojs/mux-audio — no changesEntries (2)
📦 @videojs/mux-data — 1 small size change
📦 @videojs/mux-video — no changesEntries (2)
📦 @videojs/native-hls-video — no changes📦 @videojs/shaka-video — no changes📦 @videojs/spf — no changesEntries (7)
📦 @videojs/spotify-audio — no changes📦 @videojs/tiktok-video — no changes📦 @videojs/twitch-video — no changes📦 @videojs/vimeo-video — no changes📦 @videojs/wistia-video — no changesEntries (2)
📦 @videojs/youtube-video — no changesℹ️ How to interpretEach 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 |
luwes
left a comment
There was a problem hiding this comment.
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.
1636b0d to
989d03c
Compare
c94f38a to
1b6067c
Compare
1b6067c to
848dcb1
Compare
faa4908 to
ef89016
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ 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.
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>
30a205f to
12b5cb1
Compare
✅ Deploy Preview for vjs-registry ready!
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>

Summary
Split the standalone React thumbnail into
Thumbnail.RootandThumbnail.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
<Thumbnail />usage with the compoundThumbnail.Root/Thumbnail.ImageAPISlider.Thumbnailas the existing convenience component, now composed from the new parts internallyThumbnail.ImageThumbnailCore.resolveCrossOriginbetween the HTML element and the React imageconnect()stay quiet when a settled image is handed back after a ref swapmedia-thumbnail-*class namesThumbnailcomponent anatomy (Root,Image) in core so skins can compose a standalone thumbnail, type the nestedSlider.Thumbnailparts from the same props, and map the standalone component in the HTML skin targetcrossOriginintocross-origin;crossorigin,fetchpriority,srcset,tabindex, and friends now emit their real namesBreaking change
React consumers migrate from
<Thumbnail time={time} />to<Thumbnail.Root time={time}><Thumbnail.Image /></Thumbnail.Root>.ThumbnailPropsis replaced byThumbnailRootPropsandThumbnailImageProps.Testing
pnpm -F @videojs/core test src/dom/ui/tests/thumbnail.test.ts src/core/ui/thumbnailpnpm -F @videojs/react test src/ui/thumbnail src/ui/slider/tests/slider-thumbnail.test.tsxpnpm -F @videojs/html test src/ui/thumbnail src/ui/slider/tests/slider-thumbnail-element.test.tspnpm vp run @videojs/react#buildpnpm typecheckpnpm lintNote
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 ownstime, thumbnail resolution, sizing, anddata-*state; the image ownscrossOrigin,loading,fetchPriority, refs, and therenderescape hatch so overlays can sit as siblings.SliderThumbnailkeeps the same external shape but is built from those parts internally and still injects pointertime. Core typings andvjsccomponent metadata are split to match (ThumbnailProps/ThumbnailImageProps, dedicatedThumbnailcomponent definition, slider thumbnail omitstimeon the root part).Shared
ThumbnailCore.resolveCrossOriginreplaces duplicated logic in the HTML custom element; the DOMcreateThumbnailhandle gainsdisconnectImg, 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 andhtmlAttributeNamealiases (e.g.crossOrigin→crossorigin) are updated for the new anatomy; docs and demos migrate toThumbnail.Root/Thumbnail.Image.Reviewed by Cursor Bugbot for commit 39c7c1f. Bugbot is set up for automated code reviews on this repo. Configure here.