feat(evo-video): custom video component replacing shaka-player - #916
feat(evo-video): custom video component replacing shaka-player#916LuLaValva wants to merge 10 commits into
Conversation
Adds evo-video, a Marko 6 video player built on a native <video> element with a skin-styled control bar, replacing the shaka-player based ebay-video approach. DASH/HLS engines load on demand with fallback across @source entries. Controllable playing / volume / muted / language / fullscreen / currentTime inputs; label-gated optional controls (seek, captions, audio, volume slider, report, fullscreen); poster, loading and error states; offscreen-pause, autoplay coordination and play-view behaviors; overlay @nav variant. Also flips attribute precedence in evo-select so explicit attributes win over spread html input. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: bca57b3 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
Pull request overview
This PR introduces a new video Skin CSS component and an evo-video Marko 6 player built on the native <video> element (with on-demand DASH/HLS engine loading), alongside small keyboard-navigation fixes and an evo-select attribute-precedence adjustment.
Changes:
- Add
videoSkin styling primitives (controls bar, popovers, overlays, fullscreen) and documentation pages/metadata. - Add
packages/evo-marko/src/tags/evo-videoMarko component + Storybook + tests, using dynamic imports for DASH/HLS playback engines. - Adjust keyboard handling to prevent page scroll during roving tabindex/menu navigation, and flip
evo-selectattribute precedence so explicit attrs win over spread input.
Reviewed changes
Copilot reviewed 26 out of 29 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/routes/_index/components/video/css+page.marko | New CSS documentation page with demos/snippets for the video Skin API. |
| src/routes/_index/components/video/css+meta.json | Docs metadata for the CSS page. |
| src/routes/_index/components/video/+page.marko | New overview docs page for the component. |
| src/routes/_index/components/video/+meta.json | Docs metadata for the overview page. |
| src/data/component-metadata.json | Registers video in the docs component registry and links Skin Storybook path. |
| packages/skin/src/sass/video/video.scss | Implements new .video BEM styles and related primitives; keeps legacy .video-player styles. |
| packages/skin/dist/video/video.css | Regenerated dist CSS for the new video styles. |
| packages/evo-marko/src/tags/tags/evo-roving-tabindex/index.marko | Prevent default arrow-key behavior to avoid scrolling during roving focus navigation. |
| packages/evo-marko/src/tags/evo-video/video.stories.ts | Adds Storybook stories and argTypes for evo-video. |
| packages/evo-marko/src/tags/evo-video/test/test.browser.ts | Adds browser/unit tests for evo-video behavior and control gating. |
| packages/evo-marko/src/tags/evo-video/style.ts | Imports @ebay/skin/video for evo-video. |
| packages/evo-marko/src/tags/evo-video/README.md | Adds component README (currently with placeholder Storybook links). |
| packages/evo-marko/src/tags/evo-video/index.marko | Implements the Marko 6 evo-video component, state sync scripts, and media engine lifecycle. |
| packages/evo-marko/src/tags/evo-video/examples/with-track.marko | Example: side-loaded captions track. |
| packages/evo-marko/src/tags/evo-video/examples/with-nav.marko | Example: overlay nav link variant. |
| packages/evo-marko/src/tags/evo-video/examples/default.marko | Example: default usage (with width/height passthrough). |
| packages/evo-marko/src/tags/evo-video/examples/controlled.marko | Example: controlled playing/muted/volume usage. |
| packages/evo-marko/src/tags/evo-video/examples/captions.marko | Example: captions (with a Marko type-check workaround note). |
| packages/evo-marko/src/tags/evo-select/index.marko | Moves spread ...htmlInput before explicit attrs so explicit attrs/bindings win. |
| packages/evo-marko/src/tags/evo-menu/index.marko | Prevent default Enter/Space behavior to avoid scrolling while selecting menu items. |
| packages/evo-marko/package.json | Adds @videojs/* dependencies used for on-demand DASH/HLS loading. |
| package-lock.json | Lockfile updates for the new @videojs/* dependency tree. |
| agent-feedback/items/2026-08-28-video-captions-offset-firefox.md | Tracks Firefox captions-offset gap (agent-feedback item). |
| agent-feedback/items/2026-08-28-marko-intersection-collapse-staleness.md | Tracks Marko collapse bug notes (agent-feedback item). |
| agent-feedback/items/2026-08-28-gitignore-vitest-attachments.md | Suggests ignoring vitest attachments (agent-feedback item). |
| agent-feedback/items/2026-08-28-evo-react-dialog-close-timeout.md | Tracks flaky/slow dialog test (agent-feedback item). |
| agent-feedback/items/2026-08-28-evo-marko-build-skips-tests.md | Notes build-vs-test coverage gap (agent-feedback item). |
| .changeset/add-evo-video.md | Changeset for @ebay/skin + @evo-web/marko additions and behavior notes. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
PR Preview DeployedWebsite • commit bca57b3 |
The report control is now a consumer-owned icon button: @report spreads its attributes (aria-label, onClick, anything else) onto the button in the control bar, body content replaces the default flag icon, and the class merges with video__control. The button renders only when the attr tag is provided. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…utton The report attr tag is typed as evo-icon-button's Input and spreads onto an <evo-icon-button transparent> in the control bar, so consumers get the design-system button (a11yText required by the types, badge, href, partiallyDisabled, onEscape) rather than a bare <button>. Body content still replaces the default flag icon and class still merges with video__control. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Attr tags cannot be expressed through storybook controls, so @report gets a dedicated example/story like the other attr-tag features. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Wrapping evo-icon-button lost the control bar's hover styles (its icon-btn classes fight video__control's state layer), so the report attr tag is back on a native <button class="video__control">. The type still forces labeling: a11yText is required and maps to aria-label, with raw aria-label omitted from the accepted attributes; everything else passes through and body content replaces the default flag icon. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Activating the poster play button removed it from the document and dropped focus on <body>. The overlay click now flags a focus handoff, and once playback starts and the controls enter the document, an effect focuses the controls' play/pause button. Clicks on the video surface clear the pending handoff so pointer-driven playback never steals focus. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The controls now attach on playback intent (started = played || playing) instead of waiting for the playing event, the overlay click sets a single flag, and one effect keyed on `started` focuses the controls' play button post-commit. Handler-side rAF/microtask focusing cannot work: Marko commits on its own animation frame after the handler's, so the button is still detached when a handler-scheduled callback runs. No clearing bookkeeping needed - only the overlay sets the flag, so surface clicks and autoplay never steal focus, and a failed play attempt just defers the handoff to whenever playback actually starts. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- guard attachMedia against a stale async engine attach when the source changes mid-load - rename @source's engine-selection attribute from `type` to `engine` so the native MIME `type` attribute is no longer shadowed - skip unlabeled text tracks in the captions menu and tolerate invalid BCP-47 tags instead of throwing from Intl.DisplayNames - document @source's native <source> attribute passthrough in storybook - fix README storybook links and CSS doc page wording Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
c44dc5d to
acefa5a
Compare
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
do we need to have this file in git?
There was a problem hiding this comment.
Yes, typically we include it! Makes it so that types work out of the box, before running a marko-run build
Created a new
videoCSS component and<evo-video>Marko component using primitives fromvideojsinstead of depending on the<shaka-player>library.Component decisions:
<evo-video>API decisions:a11y*Textdecides whether an element will be includedccrequiresa11yCaptionsTexta11yMuteText+a11yUnmuteText= just a mute/unmute buttona11yVolumeTextadds a volume slidera11yFullscreenTexta11ySeekTextis absentBonus change
<evo-select>had a few tiny bugs that I surfaced while wrapping it, not worth a separate PR