Skip to content

feat(sandbox): fold the skins playground into the sandbox - #2586

Merged
mihar-22 merged 40 commits into
mainfrom
feat/sandbox-playground
Sep 3, 2026
Merged

feat(sandbox): fold the skins playground into the sandbox#2586
mihar-22 merged 40 commits into
mainfrom
feat/sandbox-playground

Conversation

@mihar-22

@mihar-22 mihar-22 commented Sep 2, 2026

Copy link
Copy Markdown
Member

Stacked on #2585.

Summary

The skins playground and the sandbox overlapped: both loaded skins, both switched styling, skin, and media, and only one of them had compare, a width slider, color scheme, direction, preference badges, and a copyable report. This PR moves all of that into the sandbox, lets the sandbox load skins from the framework packages, the Shadcn registry, or the authored sources compiled in the workspace, points the skin-parity suite at the sandbox, and removes the playground. One commit per step, in the order below.

Changes

  • One template runtime. createHtmlSandbox owns the shell's selections, the latest-skin guard, <media-i18n>, and the change subscriptions for every html page; useSandbox does the same for react. A template is the player it mounts, its media markup, and what an attribute cannot carry.
  • One media table. app/media.ts describes each media engine once. The shell, navbar, and CDN page derive their source lists, defaults, and disabled controls from it, and a unit test pins the lists and the template coverage. The axis is media now; ?preset= still resolves.
  • Width, color scheme, direction, captions. A width slider sizes the player through --sandbox-player-width; a preview opens at its skin's own width until the control is touched. Color scheme pins color-scheme on the shell and the preview, and the dark: variant follows the resolved scheme. Direction pins the document and the player, which otherwise derives one from its locale. Captions adds one or two subtitle tracks through the runtimes. All of it travels in the URL.
  • Where skins come from. A skins axis: the framework packages (CSS), the Shadcn registry (CSS for both platforms, Tailwind for React; the html registry install was always a CSS skin), or the authored sources, compiled on request through the skins' Vite preset inside the workspace and disabled elsewhere. Setup installs the registry's React CSS catalog beside the Tailwind one under its own alias. The preset is loaded through vite.workspace.config.ts, which the dev and build tasks pass as --config once their dependencies are built; the task config itself never imports the compiler, because Vite+ reads it before anything is built.
  • Compare and mirror. Two frames that differ on one axis, styling, skin source, skin, or platform, and share everything else, side by side or stacked, with a summary line and per-panel labels. An optional mirror carries play, pause, seeks, volume, mute, rate, and caption selection between the panels through the media element.
  • Report. A button copies a markdown report with the URL, branch and commit, the selection in words, each panel's URL, browser, viewport, the detected preferences, and the last errors the frames relayed. The preference badges sit in the settings menu and follow DevTools emulation.
  • Parity on the sandbox. The skin-parity suite opens the sandbox's compare mode, resolves each panel's frame, and reads boxes in frame coordinates. Four error-dialog baselines are regenerated: the React ones had the playground's own heading rule leaking into the dialog title, the html ones had caught the OK button mid-transition. The live html cases exposed a sandbox bug, the live video player element was never imported, now fixed and asserted.
  • Playground removed. packages/skins/dev, its Tailwind entry, task, and scripts are gone; pnpm -F @videojs/skins dev regenerates package inputs and points at the sandbox.
  • Compiler adapter. The Vite adapter in vjsc parsed every module it wrapped as a script, which failed the first production build through the plugin on the graph plugin's virtual stylesheets. It now parses script modules only, with a test.
  • Bundler consumers. The registry suite also scaffolds a webpack 5 React project and an Rspack HTML project, installs the skins with the stock Shadcn CLI, builds them, and drives the built output.

Testing

  • pnpm -F @videojs/sandbox test: 26 unit tests for the media table, skin sources, compare panels, and the report.
  • Sandbox E2E suite, cold server, before and after each commit: 59 passed and 9 skipped at the start; the suite grew with each feature and is green at the end.
  • Skin-parity suite against the sandbox: 216 of 218, in about four minutes. The two misses are the keyboard-feedback contract, which fails at the same rate against the playground (4 of 12 repeats), and one live-video motion case that passed 12 of 12 on repeat.
  • Registry suite with the two new consumers: 5 passed; setup takes about 90 seconds.
  • pnpm --workspace-root build:sandbox, the command Vercel runs, from a task graph loaded with packages/vjsc/dist moved aside: the graph loads, and the build completes in about 12 seconds.

Follow-ups

  • The keyboard-feedback parity cases read transition contracts while indicators are mid-lifecycle and flake either way; they deserve a deterministic wait.
  • Pointer mirroring at normalised coordinates, as a complement to state mirroring.
  • The other two bundler cells, webpack + HTML and Rspack + React, are one project entry each.

🤖 Generated with Claude Code


Note

Medium Risk
Large surface area across sandbox shell, skin loading paths, and visual parity E2E; behavior changes are mostly dev/demo and test infrastructure rather than published player APIs.

Overview
Consolidates skin development and parity testing into @videojs/sandbox, replacing the separate skins playground with a richer shell: URL-driven media (replacing preset), skin provenance (package / registry / authored), side-by-side compare and mirror playback, width/scheme/direction/captions, and a copyable report with errors and preferences.

Runtime refactors unify HTML (createHtmlSandbox) and React (useSandbox) around shared shell state; skins load through package imports, Shadcn registry templates, or workspace-authored VJSC modules (vite.workspace.config.ts). CI adds @videojs/sandbox, runs prepare-template.ts before StackBlitz uploads, and skin-parity E2E now boots the sandbox compare UI (iframe-aware helpers, updated baselines).

Registry E2E gains webpack and rspack consumer projects with static dist/ serving; player E2E switches to Vite+ (vp). New sandbox Playwright specs cover compare, mirror, report, shell controls, and authored skins.

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

@vercel

vercel Bot commented Sep 2, 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 3, 2026 8:06pm UTC

Request Review

@pkg-pr-new

pkg-pr-new Bot commented Sep 2, 2026

Copy link
Copy Markdown
@videojs/core

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

@videojs/element

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

@videojs/html

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

@videojs/media

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

@videojs/react

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

@videojs/spf

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

@videojs/store

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

@videojs/utils

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

commit: 03bb344

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Size Report

🎨 @videojs/html

Path Base initial PR initial Initial diff Lazy diff
/video/minimal-skin 11.27 kB 61.46 kB +50.19 kB (+445.5%) 0 B
/video/skin 11.05 kB 61.34 kB +50.29 kB (+455.0%) 0 B
/audio/minimal-skin 8.24 kB 45.76 kB +37.52 kB (+455.5%) 0 B
/audio/skin 8.01 kB 45.52 kB +37.51 kB (+468.5%) 0 B
/live-video/minimal-skin 9.09 kB 49.42 kB +40.33 kB (+443.6%) 0 B
/live-video/skin 9.10 kB 49.42 kB +40.32 kB (+442.9%) 0 B
/live-audio/minimal-skin 6.62 kB 35.39 kB +28.78 kB (+435.0%) 0 B
/live-audio/skin 6.60 kB 35.40 kB +28.80 kB (+436.1%) 0 B
/video (default) 19.96 kB 62.68 kB +42.72 kB (+214.1%) 0 B
/video (default + hls) 159.72 kB 201.75 kB +42.02 kB (+26.3%) 0 B
/video (minimal) 20.21 kB 63.04 kB +42.82 kB (+211.9%) 0 B
/video (minimal + hls) 159.93 kB 202.25 kB +42.31 kB (+26.5%) 0 B
/audio (default) 13.34 kB 47.02 kB +33.68 kB (+252.5%) 0 B
/audio (minimal) 13.60 kB 47.23 kB +33.63 kB (+247.2%) 0 B
Small changes (16, ≤ 300 B)
Path Base initial PR initial Initial diff Lazy diff
/video/minimal-skin.css 7.63 kB 7.65 kB +26 B (+0.3%)
/video/skin.css 7.42 kB 7.46 kB +45 B (+0.6%)
/video/minimal-skin2 8.08 kB 8.09 kB +5 B (+0.1%)
/video/skin2 7.90 kB 7.95 kB +52 B (+0.6%)
/audio/minimal-skin.css 5.51 kB 5.53 kB +17 B (+0.3%)
/audio/skin.css 5.32 kB 5.34 kB +20 B (+0.4%)
/audio/minimal-skin2 5.82 kB 5.83 kB +15 B (+0.3%)
/audio/skin2 5.64 kB 5.65 kB +11 B (+0.2%)
/live-video/minimal-skin.css 6.17 kB 6.21 kB +40 B (+0.6%)
/live-video/skin.css 6.16 kB 6.18 kB +18 B (+0.3%)
/live-video/minimal-skin2 6.52 kB 6.55 kB +28 B (+0.4%)
/live-video/skin2 6.56 kB 6.58 kB +29 B (+0.4%)
/live-audio/minimal-skin.css 4.38 kB 4.39 kB +15 B (+0.3%)
/live-audio/skin.css 4.35 kB 4.37 kB +16 B (+0.4%)
/live-audio/minimal-skin2 4.63 kB 4.64 kB +15 B (+0.3%)
/live-audio/skin2 4.61 kB 4.63 kB +15 B (+0.3%)
Presets (7)
Entry Initial Lazy
/video (default) 62.68 kB 56.87 kB
/video (default + hls) 201.75 kB 56.87 kB
/video (minimal) 63.04 kB 56.87 kB
/video (minimal + hls) 202.25 kB 56.87 kB
/audio (default) 47.02 kB 56.87 kB
/audio (minimal) 47.23 kB 56.87 kB
/background 11.57 kB 56.87 kB
Media (18)
Entry Initial
/media/mux-video 142.40 kB
/media/mux-audio 142.23 kB
/media/background-video 1.16 kB
/media/cloudflare-video 6.28 kB
/media/dash-video 211.61 kB
/media/hls-audio 22.09 kB
/media/hls-background-video 16.80 kB
/media/hls-video 28.04 kB
/media/hlsjs-video 141.22 kB
/media/mux-background-video 16.83 kB
/media/native-hls-video 7.57 kB
/media/shaka-video 199.18 kB
/media/spotify-audio 6.27 kB
/media/tiktok-video 6.33 kB
/media/twitch-video 6.22 kB
/media/vimeo-video 13.05 kB
/media/wistia-video 60.23 kB
/media/youtube-video 6.81 kB
Extensions (2)
Entry Initial
/extensions/google-cast 6.52 kB
/extensions/mux-data 26.94 kB
Players (5)
Entry Initial Lazy
/video/player 9.70 kB 56.87 kB
/audio/player 6.14 kB 56.87 kB
/background/player 4.46 kB 56.87 kB
/live-video/player 9.06 kB 56.87 kB
/live-audio/player 6.15 kB 56.87 kB
Skins (29)
Entry Type Initial Lazy
/video/minimal-skin.css css 7.65 kB
/video/skin.css css 7.46 kB
/video/minimal-skin js 61.46 kB 56.87 kB
/video/minimal-skin2 js 8.09 kB
/video/skin js 61.34 kB 56.87 kB
/video/skin2 js 7.95 kB
/audio/minimal-skin.css css 5.53 kB
/audio/skin.css css 5.34 kB
/audio/minimal-skin js 45.76 kB 56.87 kB
/audio/minimal-skin2 js 5.83 kB
/audio/skin js 45.52 kB 56.87 kB
/audio/skin2 js 5.65 kB
/background/skin.css css 139 B
/background/skin js 9.81 kB 56.87 kB
/background/skin2 js 187 B
/live-video/minimal-skin.css css 6.21 kB
/live-video/skin.css css 6.18 kB
/live-video/minimal-skin js 49.42 kB 56.87 kB
/live-video/minimal-skin2 js 6.55 kB
/live-video/skin js 49.42 kB 56.87 kB
/live-video/skin2 js 6.58 kB
/live-audio/minimal-skin.css css 4.39 kB
/live-audio/skin.css css 4.37 kB
/live-audio/minimal-skin js 35.39 kB 56.87 kB
/live-audio/minimal-skin2 js 4.64 kB
/live-audio/skin js 35.40 kB 56.87 kB
/live-audio/skin2 js 4.63 kB
/global.css css 190 B
/shared.css css 118 B
UI Components (62)
Entry Initial Lazy
/ui/airplay-button 11.26 kB 56.87 kB
/ui/alert-dialog 8.79 kB 56.87 kB
/ui/audio-track-radio-group 11.38 kB 56.87 kB
/ui/buffering-indicator 8.61 kB 56.87 kB
/ui/captions-button 11.51 kB 56.87 kB
/ui/captions-radio-group 11.46 kB 56.87 kB
/ui/cast-button 11.25 kB 56.87 kB
/ui/container 9.47 kB 56.87 kB
/ui/controls 8.77 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.38 kB 56.87 kB
/ui/fullscreen-button 11.27 kB 56.87 kB
/ui/gesture 9.56 kB 56.87 kB
/ui/hotkey 9.97 kB 56.87 kB
/ui/live-button 9.74 kB 56.87 kB
/ui/menu 18.45 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.22 kB 56.87 kB
/ui/play-button 11.23 kB 56.87 kB
/ui/playback-rate-button 11.32 kB 56.87 kB
/ui/playback-rate-radio-group 11.37 kB 56.87 kB
/ui/popover 8.57 kB 56.87 kB
/ui/poster 8.67 kB 56.87 kB
/ui/quality-radio-group 11.97 kB 56.87 kB
/ui/seek-button 11.27 kB 56.87 kB
/ui/seek-indicator 12.69 kB 56.87 kB
/ui/seek-indicator-value 1.10 kB
/ui/slider 11.65 kB 56.87 kB
/ui/slider-preview 2.01 kB 56.87 kB
/ui/status-announcer 10.59 kB 56.87 kB
/ui/status-indicator 13.02 kB 56.87 kB
/ui/status-indicator-value 1.10 kB
/ui/thumbnail 9.84 kB 56.87 kB
/ui/time 10.80 kB 56.87 kB
/ui/time-slider 13.02 kB 56.87 kB
/ui/time-slider-chapter-title 8.79 kB 56.87 kB
/ui/time-slider-chapters 9.64 kB 56.87 kB
/ui/title 8.17 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.01 kB 56.87 kB
/ui/volume-indicator-fill 1.11 kB
/ui/volume-indicator-value 1.10 kB
/ui/volume-popover 14.74 kB 56.87 kB
/ui/volume-slider 12.31 kB 56.87 kB
⚛️ @videojs/react — 8 small size changes
Path Base initial PR initial Initial diff Lazy diff
/video/minimal-skin.css 7.49 kB 7.52 kB +35 B (+0.5%)
/video/skin.css 7.28 kB 7.34 kB +56 B (+0.8%)
/audio/minimal-skin.css 5.36 kB 5.37 kB +15 B (+0.3%)
/audio/skin.css 5.16 kB 5.18 kB +21 B (+0.4%)
/live-video/minimal-skin.css 6.04 kB 6.07 kB +28 B (+0.5%)
/live-video/skin.css 6.02 kB 6.05 kB +30 B (+0.5%)
/live-audio/minimal-skin.css 4.22 kB 4.24 kB +14 B (+0.3%)
/live-audio/skin.css 4.20 kB 4.21 kB +19 B (+0.4%)
Presets (7)
Entry Initial Lazy
/video (default) 50.60 kB 56.87 kB
/video (default + hls) 188.44 kB 56.87 kB
/video (minimal) 50.74 kB 56.87 kB
/video (minimal + hls) 188.48 kB 56.87 kB
/audio (default) 39.53 kB 56.87 kB
/audio (minimal) 39.57 kB 56.87 kB
/background 581 B 56.87 kB
Media (22)
Entry Initial
/media/mux-video/hls-js 140.61 kB
/media/mux-video/spf 27.39 kB
/media/mux-audio/hls-js 140.55 kB
/media/mux-audio/spf 21.32 kB
/media/background-video 402 B
/media/cloudflare-video 4.34 kB
/media/dash-video 210.29 kB
/media/hls-audio 20.33 kB
/media/hls-background-video 16.46 kB
/media/hls-video 26.34 kB
/media/hlsjs-video 139.44 kB
/media/mux-audio 140.56 kB
/media/mux-background-video 16.45 kB
/media/mux-video 140.54 kB
/media/native-hls-video 5.76 kB
/media/shaka-video 197.52 kB
/media/spotify-audio 4.22 kB
/media/tiktok-video 4.18 kB
/media/twitch-video 4.30 kB
/media/vimeo-video 11.19 kB
/media/wistia-video 60.05 kB
/media/youtube-video 4.86 kB
Extensions (2)
Entry Initial
/extensions/google-cast 5.34 kB
/extensions/mux-data 25.70 kB
Players (5)
Entry Initial Lazy
/video/player 7.56 kB 56.87 kB
/audio/player 4.00 kB 56.87 kB
/background/player 2.27 kB 56.87 kB
/live-video/player 6.96 kB 56.87 kB
/live-audio/player 3.99 kB 56.87 kB
Skins (18)
Entry Type Initial Lazy
/video/minimal-skin.css css 7.52 kB
/video/skin.css css 7.34 kB
/video/minimal-skin js 50.59 kB 56.87 kB
/video/skin js 50.49 kB 56.87 kB
/audio/minimal-skin.css css 5.37 kB
/audio/skin.css css 5.18 kB
/audio/minimal-skin js 39.47 kB 56.87 kB
/audio/skin js 39.41 kB 56.87 kB
/background/skin.css css 90 B
/background/skin js 277 B
/live-video/minimal-skin.css css 6.07 kB
/live-video/skin.css css 6.05 kB
/live-video/minimal-skin js 42.56 kB 56.87 kB
/live-video/skin js 42.52 kB 56.87 kB
/live-audio/minimal-skin.css css 4.24 kB
/live-audio/skin.css css 4.21 kB
/live-audio/minimal-skin js 30.37 kB 56.87 kB
/live-audio/skin js 30.35 kB 56.87 kB
UI Components (39)
Entry Initial Lazy
/ui/airplay-button 10.45 kB 56.87 kB
/ui/alert-dialog 4.73 kB 56.87 kB
/ui/audio-track 7.93 kB 56.87 kB
/ui/audio-track-radio-group 9.48 kB 56.87 kB
/ui/buffering-indicator 7.80 kB 56.87 kB
/ui/captions-button 10.44 kB 56.87 kB
/ui/captions-radio-group 9.59 kB 56.87 kB
/ui/cast-button 10.44 kB 56.87 kB
/ui/controls 7.71 kB 56.87 kB
/ui/dialog 4.75 kB 56.87 kB
/ui/error-dialog 11.80 kB 56.87 kB
/ui/fullscreen-button 10.40 kB 56.87 kB
/ui/gesture 7.99 kB 56.87 kB
/ui/hotkey 8.38 kB 56.87 kB
/ui/live-button 8.80 kB 56.87 kB
/ui/menu 19.45 kB 56.87 kB
/ui/mute-button 10.44 kB 56.87 kB
/ui/pip-button 10.39 kB 56.87 kB
/ui/play-button 10.37 kB 56.87 kB
/ui/playback-rate 7.99 kB 56.87 kB
/ui/playback-rate-button 10.37 kB 56.87 kB
/ui/playback-rate-radio-group 9.53 kB 56.87 kB
/ui/popover 8.16 kB 56.87 kB
/ui/poster 7.57 kB 56.87 kB
/ui/quality 8.42 kB 56.87 kB
/ui/quality-radio-group 9.95 kB 56.87 kB
/ui/seek-button 10.41 kB 56.87 kB
/ui/seek-indicator 11.97 kB 56.87 kB
/ui/slider 12.76 kB 56.87 kB
/ui/status-announcer 10.10 kB 56.87 kB
/ui/status-indicator 12.29 kB 56.87 kB
/ui/thumbnail 8.73 kB 56.87 kB
/ui/time 9.77 kB 56.87 kB
/ui/time-slider 14.17 kB 56.87 kB
/ui/title 7.28 kB 56.87 kB
/ui/tooltip 8.93 kB 56.87 kB
/ui/volume-indicator 12.33 kB 56.87 kB
/ui/volume-popover 14.20 kB 56.87 kB
/ui/volume-slider 12.14 kB 56.87 kB
🧩 @videojs/core — no changes
Entries (76)
Entry Initial Lazy
. 13.15 kB
/dom 22.53 kB 56.87 kB
/vjsc 1.82 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/media

Path Base initial PR initial Initial diff Lazy diff
/dom/dash 209.83 kB 3.28 kB -206.54 kB (-98.4%)
/dom/wistia 60.09 kB 1.89 kB -58.20 kB (-96.9%)
Entries (23)
Entry Initial
. 1.07 kB
/dom 121 B
/dom/dash 3.28 kB
/dom/wistia 1.89 kB
/dom/audio-host 1.10 kB
/dom/cloudflare 3.69 kB
/dom/custom-media-element 2.13 kB
/dom/dash 209.83 kB
/dom/google-cast 4.06 kB
/dom/hls-js 139.16 kB
/dom/media-host 1.20 kB
/dom/media-played-ranges 576 B
/dom/mux 162.88 kB
/dom/native-hls 5.25 kB
/dom/shaka 197.02 kB
/dom/spotify 3.58 kB
/dom/tiktok 3.57 kB
/dom/twitch 3.62 kB
/dom/video-host 1.39 kB
/dom/vimeo 10.62 kB
/dom/wistia 60.09 kB
/dom/youtube 4.25 kB
/media-tracks 2.05 kB
📦 @videojs/spf — no changes
Entries (10)
Entry Initial
. 4.55 kB
/dom 6.60 kB
/hls 22.06 kB
/media-tracks 504 B
/hls-background-video 15.89 kB
/hls-audio 19.82 kB
/hls-video 25.85 kB
/mux-audio 20.76 kB
/mux-background-video 15.89 kB
/mux-video 26.67 kB

ℹ️ 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.

@netlify

netlify Bot commented Sep 2, 2026

Copy link
Copy Markdown

Deploy Preview for vjs10-site ready!

Name Link
🔨 Latest commit 679b447
🔍 Latest deploy log https://app.netlify.com/projects/vjs10-site/deploys/6a99d2fedc33ab00074b1a8f
😎 Deploy Preview https://deploy-preview-2586--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.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

E2E triage: real regression. #2605 tracks the repeatable cross-browser HTML/React buffering-indicator failures after the Vite+ player-server change, plus the related migrated visual-contract failures. Assigned to @mihar-22.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

E2E triage: real regression. The buffering indicator stays hidden after waiting in HTML and React on Chromium and WebKit; the run also has deterministic visual and skin-parity failures. Reused and updated #2605.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

E2E triage: real regression. #2605 tracks the repeated Chromium/WebKit HTML/React buffering-indicator failure after waiting, plus the related visual and skin-parity failures from this run. Assigned to @mihar-22.

…e its output

pnpm exec exited without output in the CI container while npx worked from the previous layout, so use
npx from the e2e package and pipe the server's stdout and stderr into the Playwright log.
The workspace overrides every vite dependency with the Vite+ core package, which ships only the vp
binary, so neither pnpm exec vite nor npx vite can start the player app in a clean install. Run vp dev
from the e2e package against the app directory, as the app's own dev script and the sandbox already do.
The time label sat two units higher than the legacy default skin placed it and the Minimal label and
thumbnail sat two and three units higher, with extra horizontal padding the legacy Minimal label never
had. The offsets return to 10.5 default and 5 Minimal for labels and 11 for the Minimal thumbnail.
The navbar keeps what plays: platform, media, and source. The skin, its
styling, where it comes from, and the compare axis move into the preview
header. Width, appearance, playback, captions, language, and the detected
preferences move into an Options panel beside the preview, toggled from
the navbar and remembered across loads, so nothing covers the player.
The width control now reaches 1360px and takes an exact value.
The dark overlay colour and its blur were the only tokens still called
scrim while the utilities that used them were already named after the
backdrop. `--media-scrim` becomes `--media-backdrop`,
`--media-backdrop-filter-scrim` becomes `--media-backdrop-filter-backdrop`,
and the `bg-media-backdrop` and `backdrop-filter-media-backdrop`
utilities follow.
…registry modules

A module owned by a preset directory such as `skins/audio` was written
to that directory for every skin that used it, and that directory is
also the default theme's own. Default and Minimal audio both compiled
`time-slider.tsx` there with their own variants, and the default copy
won, so the Minimal audio slider preview in the Tailwind registry output
kept the default's fixed-width preview box and stopped short of both
edges. The Minimal theme now keeps such modules beside its skin, as it
already does for shared components.
…y module

A skin's compiled module was mapped onto a published item whenever its
own source and styles matched, so a component whose source never changes
between skins, such as the playback rate button, resolved to the shared
item even though the button it renders differs by skin. The Minimal audio
skin then rendered its rate trigger with the default theme's radius in
the Tailwind registry output. Two modules are now interchangeable only
when everything they import is interchangeable too.
`--media-backdrop-filter-backdrop` sat behind the buffering and playback
status indicators only, so it is now `--media-backdrop-filter-indicator`,
beside the `-surface` and `-dialog` filters, with the
`backdrop-filter-media-indicator` utility to match.
The define entries import their skin's internal/skins/*/register.js for
its element registrations, but package.json#sideEffects never listed that
path, so production bundlers dropped the import and packaged HTML skins
rendered without a container or controls. Pin the coverage with a test.
… escape markup values

The CDN page now adds the subtitle tracks the shell streams, the preview
pages default the skin source through defaultSkinSource so an html Tailwind
URL loads the authored skin, and the html string sinks escape the URLs they
interpolate.
Comment thread apps/sandbox/app/shell/app.tsx Outdated
Comment thread apps/sandbox/app/shared/sandbox-mirror.ts
…enable

A styling comparison puts CSS in the first panel, so constraining the
shell's styling by that panel's source sent a Tailwind selection back to
CSS. Constrain it by the selection's own resolved source instead. Mirroring
also reports the current playback state as soon as it turns on or binds a
media element, so the sibling panel does not wait for the next event.
The pkg.pr.new template is apps/sandbox alone, and it failed at every step:
pnpm could not resolve the catalog: specs or the private @videojs/icons
range, the start command ran a dev script that did not exist, pnpm 11
refused the preview packages' URL subdependencies and re-ran the install
before the task, the Vite config imported build/task.ts from the repo
root, the task graph named sibling packages, a nested tsconfig extended
the root one, and setup aborted when the hosted registry answered 404.

CI now prepares the template manifest before publishing, the start command
runs the dev task through vp with the pnpm settings the template needs, the
config carries its own task helpers and declares cross-package tasks only
inside the workspace, the shared type project moved beside tsconfig.json,
and setup degrades to package skins when the registry is unreachable, which
the shell reflects by disabling the registry sources.

@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 cefbb6a. Configure here.

Comment thread apps/sandbox/app/shared/skin-sources.ts
defaultSkinSource named the registry for React Tailwind even where setup
found no registry, so a direct Tailwind URL loaded modules that were not
there before the shell's CSS fallback ran. Pick the first available source
that publishes the styling, and fall back to the packages' CSS skin.
@mihar-22
mihar-22 merged commit ee38b1d into main Sep 3, 2026
34 of 36 checks passed
@mihar-22
mihar-22 deleted the feat/sandbox-playground branch September 3, 2026 20:28
@videojs-release videojs-release Bot mentioned this pull request Sep 3, 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