Skip to content

refactor: unify use-case, skin, and install-method pickers into shared option builders#1757

Draft
decepulis wants to merge 1 commit into
mainfrom
claude/zen-mayer-tr63m0
Draft

refactor: unify use-case, skin, and install-method pickers into shared option builders#1757
decepulis wants to merge 1 commit into
mainfrom
claude/zen-mayer-tr63m0

Conversation

@decepulis

Copy link
Copy Markdown
Collaborator

Closes #1751. Follow-up from #1732.

#1732 introduced site/src/utils/installation/renderer-options.ts — a shared, pure module (label map + buildOptions) that the docs UI picker and the @videojs/cli prompt both consume so the renderer options can't drift. This PR extends that pattern to the three remaining installation pickers: use case, skin, and install method.

What's in here

Three new shared modules alongside renderer-options.ts, each exporting a label map + a buildOptions-style function:

Module Exports Consumed by
usecase-options.ts USE_CASE_LABELS, buildOptions() UseCasePicker.tsx, CLI preset prompt
skin-options.ts SKIN_LABELS, buildOptions(useCase) SkinPicker.tsx, CLI skin prompt
install-method-options.ts INSTALL_METHOD_LABELS, buildOptions({ includeCdn }) HTMLInstallTabsClient.tsx, CLI install-method prompt
  • UI pickers consume the builders and map their surface-specific bits on top — lucide icons for the radio groups, and the CDN/package-manager panels for the install tabs. The tabs' remount/observer logic is unchanged; the tab list and labels now come from the builder (CDN first when available = the default tab).
  • CLI prompt (packages/cli/src/utils/prompts.ts) replaces PRESET_OPTIONS, skinOptionsForUseCase, and installMethodOptions with thin wrappers over the shared builders. The non-interactive --install-method validation in docs.ts now derives its accepted values from INSTALL_METHOD_LABELS (mirroring how --media already derives from RENDERER_LABELS).
  • CLI shim/config: the three modules are declared in site-modules.d.ts, aliased in tsdown.config.ts + vitest.config.ts, and asserted in site-aliases.test.ts.

Reconciled label drift

The issue flagged the skin "none" label as drifted. Reconciled, plus one more I found while wiring the tabs — both are one-line flips if you'd prefer the other direction:

Option Before (UI) Before (CLI) Now (both)
Skin "none" No Skin None (headless) None (headless)
Install CDN tab cdn CDN CDN

I picked None (headless) (more descriptive for the dev audience — explains the consequence) and CDN (acronym convention, already the CLI's label). Happy to flip either.

Note

The skin builder returns a single fixed Default option for background-video — matching the CLI today and the fact that the UI hides the skin picker entirely for that use case (SkinPickerSectionClient returns null).

Tests & verification

  • New unit tests for all three builders (__tests__/{usecase,skin,install-method}-options.test.ts), mirroring renderer-options.test.ts.
  • Site suite green (90 tests); CLI suite green (65 tests, incl. the expanded alias test exercising the new modules through the real site source).
  • Lint clean on changed files; CLI tsdown bundle builds (new aliases + shim resolve); pnpm check:workspace passes.

Note

pnpm typecheck reports ~510 errors in packages/{html,react,store} on this branch and on the base commit — a pre-existing tsgo build-state issue in a fresh checkout, unrelated to this diff. The changed files (site/, packages/cli/) add zero type errors.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TMRTUmrr3wSHjY2y1ys2f4


Generated by Claude Code

…d option builders

Extends the renderer-options.ts pattern from #1732 to the three remaining
installation pickers so the docs UI and @videojs/cli stay in lockstep — one
source of truth per picker, no drift.

- Add usecase-options.ts, skin-options.ts, and install-method-options.ts
  (label map + buildOptions) alongside renderer-options.ts.
- UI pickers (UseCasePicker, SkinPicker, HTMLInstallTabs) and the CLI prompt
  consume the shared builders; icons and tab panels are mapped on top.
- Derive the CLI's --install-method flag validation from the shared label map.
- Mirror the new modules in the CLI site-modules shim and the tsdown/vitest
  aliases, and assert their presence in site-aliases.test.ts.
- Reconcile drifted labels: skin "none" -> "None (headless)" (was "No Skin" in
  the UI); install CDN tab -> "CDN" (was lowercase "cdn").

Closes #1751.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TMRTUmrr3wSHjY2y1ys2f4
@netlify

netlify Bot commented Jun 26, 2026

Copy link
Copy Markdown

Deploy Preview for vjs10-site ready!

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

@vercel

vercel Bot commented Jun 26, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
v10-sandbox Ready Ready Preview, Comment Jun 26, 2026 9:48pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📦 Bundle Size Report

🎨 @videojs/html — no changes
Presets (7)
Entry Initial
/video (default) 44.32 kB
/video (default + hls) 183.97 kB
/video (minimal) 43.98 kB
/video (minimal + hls) 183.58 kB
/audio (default) 37.83 kB
/audio (minimal) 36.61 kB
/background 4.20 kB
Media (10)
Entry Initial
/media/background-video 1.14 kB
/media/container 1.72 kB
/media/dash-video 214.74 kB
/media/hlsjs-video 141.13 kB
/media/mux-audio 163.91 kB
/media/mux-video 163.68 kB
/media/native-hls-video 9.05 kB
/media/simple-hls-audio-only 17.15 kB
/media/simple-hls-video 18.69 kB
/media/vimeo-video 12.31 kB
Players (5)
Entry Initial
/video/player 8.07 kB
/audio/player 5.38 kB
/background/player 3.92 kB
/live-video/player 7.64 kB
/live-audio/player 5.39 kB
Skins (30)
Entry Type Initial
/video/minimal-skin.css css 5.45 kB
/video/skin.css css 5.43 kB
/video/minimal-skin js 44.01 kB
/video/minimal-skin.tailwind js 44.58 kB
/video/skin js 44.28 kB
/video/skin.tailwind js 44.98 kB
/audio/minimal-skin.css css 3.60 kB
/audio/skin.css css 3.53 kB
/audio/minimal-skin js 36.62 kB
/audio/minimal-skin.tailwind js 37.04 kB
/audio/skin js 37.80 kB
/audio/skin.tailwind js 38.25 kB
/background/skin.css css 133 B
/background/skin js 1.14 kB
/live-video/minimal-skin.css css 5.45 kB
/live-video/skin.css css 5.43 kB
/live-video/minimal-skin js 43.12 kB
/live-video/minimal-skin.tailwind js 43.58 kB
/live-video/skin js 43.08 kB
/live-video/skin.tailwind js 43.58 kB
/live-audio/minimal-skin.css css 3.60 kB
/live-audio/skin.css css 3.53 kB
/live-audio/minimal-skin js 29.73 kB
/live-audio/minimal-skin.tailwind js 29.20 kB
/live-audio/skin js 31.04 kB
/live-audio/skin.tailwind js 30.66 kB
/global.css css 176 B
/shared.css css 88 B
/tailwind.css css 228 B
/skin-element js 1.44 kB
UI Components (38)
Entry Initial
/ui/airplay-button 2.29 kB
/ui/alert-dialog 2.45 kB
/ui/alert-dialog-close 2.15 kB
/ui/alert-dialog-description 2.18 kB
/ui/alert-dialog-title 2.17 kB
/ui/buffering-indicator 2.24 kB
/ui/captions-button 2.37 kB
/ui/captions-radio-group 2.73 kB
/ui/cast-button 2.25 kB
/ui/compounds 2.85 kB
/ui/controls 2.58 kB
/ui/error-dialog 2.61 kB
/ui/fullscreen-button 2.29 kB
/ui/hotkey 2.31 kB
/ui/menu 2.63 kB
/ui/mute-button 2.27 kB
/ui/pip-button 2.28 kB
/ui/play-button 2.28 kB
/ui/playback-rate-button 2.36 kB
/ui/playback-rate-radio-group 2.78 kB
/ui/popover 2.64 kB
/ui/poster 2.14 kB
/ui/quality-radio-group 2.75 kB
/ui/seek-button 2.27 kB
/ui/seek-indicator 2.29 kB
/ui/seek-indicator-value 465 B
/ui/slider 2.62 kB
/ui/status-announcer 2.28 kB
/ui/status-indicator 2.36 kB
/ui/status-indicator-value 467 B
/ui/thumbnail 2.09 kB
/ui/time 2.60 kB
/ui/time-slider 2.64 kB
/ui/tooltip 2.59 kB
/ui/volume-indicator 2.36 kB
/ui/volume-indicator-fill 410 B
/ui/volume-indicator-value 426 B
/ui/volume-slider 2.64 kB

Sizes are marginal over the root entry point.

⚛️ @videojs/react — no changes
Presets (7)
Entry Initial
/video (default) 36.83 kB
/video (default + hls) 175.21 kB
/video (minimal) 36.91 kB
/video (minimal + hls) 175.19 kB
/audio (default) 29.97 kB
/audio (minimal) 30.04 kB
/background 754 B
Media (9)
Entry Initial
/media/background-video 575 B
/media/dash-video 213.24 kB
/media/hlsjs-video 139.64 kB
/media/mux-audio 162.26 kB
/media/mux-video 162.26 kB
/media/native-hls-video 7.39 kB
/media/simple-hls-audio-only 15.56 kB
/media/simple-hls-video 17.15 kB
/media/vimeo-video 10.58 kB
Skins (27)
Entry Type Initial
/tailwind.css css 228 B
/video/minimal-skin.css css 5.37 kB
/video/skin.css css 5.34 kB
/video/minimal-skin js 36.81 kB
/video/minimal-skin.tailwind js 42.58 kB
/video/skin js 36.73 kB
/video/skin.tailwind js 42.51 kB
/audio/minimal-skin.css css 3.47 kB
/audio/skin.css css 3.39 kB
/audio/minimal-skin js 29.98 kB
/audio/minimal-skin.tailwind js 31.76 kB
/audio/skin js 29.91 kB
/audio/skin.tailwind js 33.75 kB
/background/skin.css css 90 B
/background/skin js 272 B
/live-video/minimal-skin.css css 5.37 kB
/live-video/skin.css css 5.34 kB
/live-video/minimal-skin js 32.56 kB
/live-video/minimal-skin.tailwind js 38.22 kB
/live-video/skin js 32.58 kB
/live-video/skin.tailwind js 38.24 kB
/live-audio/minimal-skin.css css 3.47 kB
/live-audio/skin.css css 3.39 kB
/live-audio/minimal-skin js 21.74 kB
/live-audio/minimal-skin.tailwind js 24.64 kB
/live-audio/skin js 21.78 kB
/live-audio/skin.tailwind js 24.78 kB
UI Components (32)
Entry Initial
/ui/airplay-button 2.23 kB
/ui/alert-dialog 2.20 kB
/ui/buffering-indicator 2.10 kB
/ui/captions-button 2.16 kB
/ui/captions-radio-group 2.09 kB
/ui/cast-button 2.19 kB
/ui/controls 2.05 kB
/ui/error-dialog 2.24 kB
/ui/fullscreen-button 2.26 kB
/ui/gesture 2.25 kB
/ui/hotkey 2.27 kB
/ui/live-button 2.12 kB
/ui/menu 2.43 kB
/ui/mute-button 2.24 kB
/ui/pip-button 2.26 kB
/ui/play-button 2.19 kB
/ui/playback-rate 2.06 kB
/ui/playback-rate-button 2.25 kB
/ui/popover 2.64 kB
/ui/poster 2.09 kB
/ui/quality 2.10 kB
/ui/seek-button 2.20 kB
/ui/seek-indicator 2.19 kB
/ui/slider 2.26 kB
/ui/status-announcer 2.11 kB
/ui/status-indicator 2.15 kB
/ui/thumbnail 2.00 kB
/ui/time 2.05 kB
/ui/time-slider 2.29 kB
/ui/tooltip 2.59 kB
/ui/volume-indicator 2.18 kB
/ui/volume-slider 2.30 kB

Sizes are marginal over the root entry point.

🧩 @videojs/core — no changes
Entries (14)
Entry Initial
. 9.08 kB
/dom 17.02 kB
/dom/media/custom-media-element 2.09 kB
/dom/media/dash 209.07 kB
/dom/media/google-cast 4.04 kB
/dom/media/hls-js 135.76 kB
/dom/media/media-host 1.25 kB
/dom/media/media-played-ranges 576 B
/dom/media/mux 151.26 kB
/dom/media/native-hls 3.05 kB
/dom/media/simple-hls 16.47 kB
/dom/media/simple-hls-audio-only 14.92 kB
/dom/media/vimeo 9.86 kB
/media/predicate 573 B
🏷️ @videojs/element — no changes
Entries (2)
Entry Initial
. 996 B
/context 943 B
📦 @videojs/store — no changes
Entries (3)
Entry Initial
. 1.39 kB
/html 696 B
/react 360 B
🔧 @videojs/utils — no changes
Entries (10)
Entry Initial
/array 104 B
/dom 2.26 kB
/events 319 B
/function 327 B
/object 275 B
/predicate 265 B
/string 231 B
/style 190 B
/time 478 B
/number 158 B
📦 @videojs/spf — no changes
Entries (4)
Entry Initial
. 4.45 kB
/dom 6.33 kB
/hls 15.37 kB
/background-video 12.85 kB

ℹ️ How to interpret

JS sizes are initial static graph totals (minified + brotli). Lazy dynamic chunks are shown separately when present.

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

Run pnpm size locally to check current initial sizes.

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.

Chore: Unify the Remaining Pickers (Use-Case, Skin, Install-Method) into Shared Option Builders

2 participants