refactor(packages)!: replace button availability with disabled and hidden state#1474
Open
refactor(packages)!: replace button availability with disabled and hidden state#1474
Conversation
Covers the rationale for using aria-disabled over HTML disabled, HTML hidden for unsupported features, and separate data-disabled/data-hidden styling hooks across cast, fullscreen, and pip buttons. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…dden state Cast, fullscreen, and pip buttons now expose `disabled` (non-interactive) and `hidden` (unsupported) state derived from `availability` and the `disabled` prop, instead of relying on the raw availability enum at the attribute layer. - `getAttrs` returns `aria-disabled` from state and the native HTML `hidden` attribute when the feature is unsupported. New `data-disabled` and `data-hidden` data attribute mappings ride along. - `toggle` short-circuits on `state.disabled` and otherwise awaits the underlying media call directly, propagating errors to the caller instead of swallowing them. - `MediaButtonElement` and `createMediaButton` now wrap the activation in try/catch with a `__DEV__` console.error and rethrow so callers see the original failure. - React buttons pass `isSupported: (s) => !s.hidden` so unsupported features render `null` rather than a hidden `<button>`. Aligns with the WAI-ARIA APG toolbar pattern (focusable disabled controls) documented in `internal/design/ui/disabled-hidden.md`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace `data-[availability=...]:hidden` with `data-[disabled]` styling classes to match the new disabled/hidden button state model. Hidden buttons use the native HTML hidden attribute; disabled buttons get reduced opacity and grayscale via data-disabled. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
PiP is unsupported on WebKit so the button receives the `hidden` attribute and is removed from the layout. Only assert `data-availability` when the pip button is visible. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tons Update the fullscreen and pip button reference pages plus the features concept page to describe the new `disabled`/`hidden` state model: HTML `hidden` for unsupported environments (or `null` in React) and `data-disabled` for non-interactive styling. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
✅ Deploy Preview for vjs10-site ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📦 Bundle Size Report🎨 @videojs/html — no changesPresets (7)
Media (8)
Players (3)
Skins (29)
UI Components (25)
Sizes are marginal over the root entry point. ⚛️ @videojs/react — no changesPresets (7)
Media (7)
Skins (26)
UI Components (20)
Sizes are marginal over the root entry point. 🧩 @videojs/core — no changesEntries (9)
🏷️ @videojs/element — no changesEntries (2)
📦 @videojs/store — no changesEntries (3)
🔧 @videojs/utils — no changesEntries (10)
📦 @videojs/spf — no changesEntries (3)
ℹ️ How to interpretAll sizes are standalone totals (minified + brotli).
Run |
Document the two pre-existing fields alongside the newly added disabled/hidden so the component reference table renders complete descriptions for every cast button state property. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The skin's `display: flex` (and `grid` on the icon variant) outranks the
user-agent `[hidden] { display: none }` rule on specificity, so feature
buttons stayed visible when the cast/fullscreen/pip cores set the native
`hidden` attribute.
Add a `&[hidden] { display: none }` rule under the high-specificity
skin selector in both default and minimal CSS, and a `[&[hidden]]:hidden`
class in the Tailwind variants so the same override works for the
Tailwind-compiled skins.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…omponent override Move the native `hidden` attribute override from the button component into the skin reset so any authored template that sets `[hidden]` stays hidden, not just media buttons. Use the doubled `[hidden][hidden]` selector under the skin root to outrank component-level `display: flex/grid` declarations. The Tailwind root composition gets the equivalent `[&_[hidden][hidden]]:hidden` class. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Initial `availability` is `'unavailable'` until the cast feature reports otherwise, so the derived `disabled` flag must also start `true` to match the invariant `disabled = props.disabled || availability !== 'available'`. Anyone reading `core.state.current` before the first `getState()` call now sees a consistent non-interactive state. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
`createButton` / `useButton` invoke `onActivate` synchronously from click and keyup handlers, so re-throwing from the wrapper produced unhandled promise rejections for benign user actions like cancelling a cast prompt or being denied fullscreen. Log the failure in `__DEV__` for visibility and let it stop there. Callers that await `core.toggle(...)` directly still observe the rejection — only the synchronous UI boundary absorbs it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit bdafdc6. Configure here.
The captions button previously relied on the now-removed `data-availability="unavailable"` skin rule to hide itself when no caption tracks were present. Extend the same `disabled`/`hidden` model already applied to cast/fullscreen/pip buttons so it stays hidden in that state without depending on availability-specific CSS. - Add `disabled` and `hidden` to `CaptionsButtonState`, derived from the `disabled` prop and whether any caption/subtitle tracks exist. - `getAttrs` returns `aria-disabled` from state and the native HTML `hidden` attribute when no tracks are available. - `toggle` short-circuits on `state.disabled`. - `data-disabled` and `data-hidden` data attribute mappings ride along. - React captions button passes `isSupported: (s) => !s.hidden` so it renders `null` when no tracks are present. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously unavailable buttons used `display: none`, which masked the
`:active { scale: 0.98 }` rule. Now that `[data-disabled]` keeps the
button visible but non-interactive, guard the press animation with
`:not([disabled]):not([data-disabled])` (and the Tailwind equivalent
`not-disabled:not-data-disabled:active:*`) so disabled buttons no
longer give misleading press feedback.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Replace the
availableboolean on buttons withdisabledandhiddenstates that follow standard ARIA patterns —aria-disabledfor non-interactive controls and HTMLhiddenfor unsupported features.Note
Medium Risk
Changes core interaction semantics for multiple control buttons (visibility/disabled behavior and error propagation), which could affect consumers’ styling and runtime behavior across browsers despite being mostly deterministic and well-tested.
Overview
Refactors the core
CastButton,FullscreenButton,PiPButton, andCaptionsButtonto derive two new state fields—disabledandhidden—from props +availability, and uses these to setaria-disabledand the native HTMLhiddenattribute.Updates data-attribute mapping and styling to use
data-disabled/data-hidden(instead of hiding viadata-availabilityCSS), adds ReactcreateMediaButtonsupport for async actions plus anisSupportedgate (feature buttons rendernullwhenhidden), and adjusts HTMLMediaButtonElement/button elements to safely invoke asyncactivate()while logging (dev-only) and preventing unhandled promise rejections.Button
toggle()implementations now short-circuit via derived state and propagate underlying API errors (tests updated accordingly); docs and e2e assertions are updated for WebKit PiP being hidden when unsupported, and a design decision doc is added to codify the pattern.Reviewed by Cursor Bugbot for commit 8bcff00. Bugbot is set up for automated code reviews on this repo. Configure here.