Skip to content

feat(html): re-export reactive primitives from @videojs/element#1472

Merged
decepulis merged 1 commit intomainfrom
feat/html-reexport-reactive
Apr 27, 2026
Merged

feat(html): re-export reactive primitives from @videojs/element#1472
decepulis merged 1 commit intomainfrom
feat/html-reexport-reactive

Conversation

@decepulis
Copy link
Copy Markdown
Collaborator

@decepulis decepulis commented Apr 27, 2026

Summary

Re-exports the reactive primitives from @videojs/element so users extending MediaElement to build custom UI components don't need to install and import from @videojs/element directly:

  • ReactiveElement, DestroyMixin (runtime values)
  • Destroyable, PropertyDeclaration, PropertyDeclarationMap, PropertyValues, ReactiveController, ReactiveControllerHost (types)

The motivating case is overriding update(changed: PropertyValues) — users need PropertyValues to type the override parameter, but it lives in @videojs/element. They're already pulling MediaElement from @videojs/html, so this puts the types in the same package.

Purely additive — no name conflicts, no breaking change. @videojs/element is already a workspace dep of @videojs/html, and the runtime values (ReactiveElement, DestroyMixin) are already pulled in transitively via MediaElement, so no bundle size cost.

Context

Suggested by @mihar-22 reviewing #1008 (this comment). The "Build your own component" guide hits the same friction repeatedly.

Test plan

  • pnpm -F @videojs/html build — types regenerated, all re-exports present in dist/dev/index.d.ts
  • pnpm -F @videojs/html test — 101 tests pass
  • pnpm check:workspace — 6/6 checks pass
  • pnpm typecheck — same baseline as origin/main (330 pre-existing errors, none introduced by this change)

🤖 Generated with Claude Code


Note

Low Risk
Low risk: this is a purely additive public API change that only re-exports existing runtime values and TypeScript types, with no behavioral changes.

Overview
@videojs/html now re-exports reactive primitives from @videojs/element, exposing ReactiveElement/DestroyMixin plus related controller/property types (e.g., PropertyValues).

This lets consumers extending MediaElement import the reactive building blocks from @videojs/html directly without adding a separate dependency/import path.

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

Re-exports `ReactiveElement`, `DestroyMixin`, `Destroyable`,
`PropertyDeclaration`, `PropertyDeclarationMap`, `PropertyValues`,
`ReactiveController`, and `ReactiveControllerHost` from `@videojs/html`.

Users extending `MediaElement` to build custom UI components need these
types (e.g., `PropertyValues` to type the `update(changed)` override).
Previously they had to install `@videojs/element` directly. Surfacing
them from `@videojs/html` matches the package they're already importing
`MediaElement` from.

Suggested by @mihar-22 on #1008 (line 196).

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

vercel Bot commented Apr 27, 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 27, 2026 3:55pm

Request Review

@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 27, 2026

Deploy Preview for vjs10-site ready!

Name Link
🔨 Latest commit 75335c7
🔍 Latest deploy log https://app.netlify.com/projects/vjs10-site/deploys/69ef86d96994c700082678fc
😎 Deploy Preview https://deploy-preview-1472--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.

@decepulis decepulis merged commit 466abb6 into main Apr 27, 2026
13 of 14 checks passed
@decepulis decepulis deleted the feat/html-reexport-reactive branch April 27, 2026 15:55
@luwes luwes mentioned this pull request Apr 24, 2026
@github-actions
Copy link
Copy Markdown
Contributor

📦 Bundle Size Report

🎨 @videojs/html — no changes
Presets (7)
Entry Size
/video (default) 28.77 kB
/video (default + hls) 161.35 kB
/video (minimal) 26.26 kB
/video (minimal + hls) 158.75 kB
/audio (default) 26.66 kB
/audio (minimal) 24.20 kB
/background 4.16 kB
Media (8)
Entry Size
/media/background-video 1.04 kB
/media/container 1.72 kB
/media/dash-video 236.54 kB
/media/hls-video 134.01 kB
/media/mux-audio 160.06 kB
/media/mux-video 160.07 kB
/media/native-hls-video 3.77 kB
/media/simple-hls-video 15.80 kB
Players (3)
Entry Size
/video/player 7.04 kB
/audio/player 5.12 kB
/background/player 3.86 kB
Skins (29)
Entry Type Size
/video/minimal-skin.css css 3.50 kB
/video/skin.css css 3.53 kB
/video/minimal-skin js 26.25 kB
/video/minimal-skin.tailwind js 26.45 kB
/video/skin js 28.77 kB
/video/skin.tailwind js 28.81 kB
/audio/minimal-skin.css css 2.54 kB
/audio/skin.css css 2.50 kB
/audio/minimal-skin js 24.20 kB
/audio/minimal-skin.tailwind js 24.38 kB
/audio/skin js 26.62 kB
/audio/skin.tailwind js 26.76 kB
/background/skin.css css 117 B
/background/skin js 1.15 kB
/live-video/minimal-skin.css css 3.50 kB
/live-video/skin.css css 3.53 kB
/live-video/minimal-skin js 25.98 kB
/live-video/minimal-skin.tailwind js 26.07 kB
/live-video/skin js 28.44 kB
/live-video/skin.tailwind js 28.54 kB
/live-audio/minimal-skin.css css 2.54 kB
/live-audio/skin.css css 2.50 kB
/live-audio/minimal-skin js 23.99 kB
/live-audio/minimal-skin.tailwind js 23.98 kB
/live-audio/skin js 26.36 kB
/live-audio/skin.tailwind js 26.42 kB
/base.css css 157 B
/shared.css css 88 B
/skin-element js 1.36 kB
UI Components (25)
Entry Size
/ui/alert-dialog 1010 B
/ui/alert-dialog-close 462 B
/ui/alert-dialog-description 390 B
/ui/alert-dialog-title 421 B
/ui/buffering-indicator 2.48 kB
/ui/captions-button 2.67 kB
/ui/cast-button 2.64 kB
/ui/compounds 4.15 kB
/ui/controls 2.35 kB
/ui/error-dialog 3.01 kB
/ui/fullscreen-button 2.62 kB
/ui/hotkey 1.85 kB
/ui/mute-button 2.67 kB
/ui/pip-button 2.63 kB
/ui/play-button 2.70 kB
/ui/playback-rate-button 2.66 kB
/ui/popover 1.84 kB
/ui/poster 2.24 kB
/ui/seek-button 2.65 kB
/ui/slider 1.52 kB
/ui/thumbnail 2.89 kB
/ui/time 2.52 kB
/ui/time-slider 3.93 kB
/ui/tooltip 2.03 kB
/ui/volume-slider 2.64 kB

Sizes are marginal over the root entry point.

⚛️ @videojs/react — no changes
Presets (7)
Entry Size
/video (default) 23.48 kB
/video (default + hls) 154.91 kB
/video (minimal) 21.11 kB
/video (minimal + hls) 152.51 kB
/audio (default) 19.06 kB
/audio (minimal) 17.61 kB
/background 755 B
Media (7)
Entry Size
/media/background-video 575 B
/media/dash-video 235.04 kB
/media/hls-video 132.49 kB
/media/mux-audio 158.70 kB
/media/mux-video 158.57 kB
/media/native-hls-video 2.26 kB
/media/simple-hls-video 14.36 kB
Skins (26)
Entry Type Size
/video/minimal-skin.css css 3.44 kB
/video/skin.css css 3.46 kB
/video/minimal-skin js 21.04 kB
/video/minimal-skin.tailwind js 24.53 kB
/video/skin js 23.40 kB
/video/skin.tailwind js 24.66 kB
/audio/minimal-skin.css css 2.44 kB
/audio/skin.css css 2.39 kB
/audio/minimal-skin js 17.52 kB
/audio/minimal-skin.tailwind js 20.04 kB
/audio/skin js 18.98 kB
/audio/skin.tailwind js 19.97 kB
/background/skin.css css 90 B
/background/skin js 272 B
/live-video/minimal-skin.css css 3.44 kB
/live-video/skin.css css 3.46 kB
/live-video/minimal-skin js 17.74 kB
/live-video/minimal-skin.tailwind js 21.15 kB
/live-video/skin js 20.14 kB
/live-video/skin.tailwind js 21.32 kB
/live-audio/minimal-skin.css css 2.44 kB
/live-audio/skin.css css 2.39 kB
/live-audio/minimal-skin js 15.72 kB
/live-audio/minimal-skin.tailwind js 18.03 kB
/live-audio/skin js 17.21 kB
/live-audio/skin.tailwind js 18.12 kB
UI Components (20)
Entry Size
/ui/alert-dialog 1.09 kB
/ui/buffering-indicator 1.79 kB
/ui/captions-button 2.02 kB
/ui/cast-button 2.04 kB
/ui/controls 1.76 kB
/ui/error-dialog 2.25 kB
/ui/fullscreen-button 2.06 kB
/ui/mute-button 2.03 kB
/ui/pip-button 2.00 kB
/ui/play-button 1.99 kB
/ui/playback-rate-button 1.89 kB
/ui/popover 1.86 kB
/ui/poster 1.67 kB
/ui/seek-button 2.10 kB
/ui/slider 2.66 kB
/ui/thumbnail 2.07 kB
/ui/time 2.06 kB
/ui/time-slider 2.36 kB
/ui/tooltip 2.17 kB
/ui/volume-slider 3.18 kB

Sizes are marginal over the root entry point.

🧩 @videojs/core — no changes
Entries (9)
Entry Size
. 4.96 kB
/dom 11.87 kB
/dom/media/custom-media-element 1.90 kB
/dom/media/dash 234.13 kB
/dom/media/google-cast 4.07 kB
/dom/media/hls 131.85 kB
/dom/media/mux 158.10 kB
/dom/media/native-hls 1.61 kB
/dom/media/simple-hls 13.73 kB
🏷️ @videojs/element — no changes
Entries (2)
Entry Size
. 996 B
/context 943 B
📦 @videojs/store — no changes
Entries (3)
Entry Size
. 1.39 kB
/html 695 B
/react 360 B
🔧 @videojs/utils — no changes
Entries (10)
Entry Size
/array 104 B
/dom 1.92 kB
/events 319 B
/function 327 B
/object 275 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.33 kB
/playback-engine 13.24 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.

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 75335c7. Configure here.

ReactiveControllerHost,
} from '@videojs/element';
// Element — reactive primitives for users extending MediaElement
export { DestroyMixin, ReactiveElement } from '@videojs/element';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Section comment misplaced between related export groups

Low Severity

The // Element section comment on line 11 only covers the runtime value export, while the type exports from the same @videojs/element package (lines 3–10) sit above it under the // Core section. This breaks the file's convention of grouping related exports under a single section comment. The comment belongs before line 3 so both the type and runtime exports from @videojs/element are grouped together under the // Element section.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 75335c7. Configure here.

decepulis added a commit that referenced this pull request Apr 27, 2026
- Drop unused `static tagName` from the full skip-intro example (the
  guide registers via `customElements.define()` directly, so the field
  is dead code from a userland perspective).
- Forward `changed: PropertyValues` to `super.update()` in both the
  intro skeleton and the full example, matching first-party convention
  and the actual `ReactiveElement` signature. `PropertyValues` now
  imports from `@videojs/html` (re-exported via #1472).
- Trim the "Place your component" skeleton — drop comments and
  `customElements.define` line — so it's a minimal anchor for what's
  required, leaving the full example as the first complete class.

Addresses review feedback on #1008.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant