-
Notifications
You must be signed in to change notification settings - Fork 7
feat: add play button component #324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
| interface PlayButtonDataAttributes { | ||
| 'data-paused'?: ''; | ||
| 'data-ended'?: ''; | ||
| 'data-disabled'?: ''; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of interest, why not use the disabled attribute?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see there's actually some more nuance here. This part in Base UI does manage disabled but carefully. They're actively removing native disabled in composite widgets (toolbars, menus, tabs).
Native disabled:
- Removes from tab order entirely
- Unfocusable
- Screen reader might skip it completely
Based on what I'm gathering, user should be able to tab through and hear "play button, disabled" rather than it vanishing from keyboard navigation. So we would set aria-disabled="true" to provide a hint, and I guess data-disabled is for styling/consistency/docs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That all makes sense! Good points. A related nit though; if we're going with aria-disabled, why don't we just use that for styling etc too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback. Updated to remove data-disabled here.
We can use disabled or aria-disabled to style.
| - `aria-label: state.label` | ||
| - `data-paused`, `data-ended`, `data-disabled` (boolean attributes) | ||
| - `onClick` handler | ||
| - `onKeyDown` handler (Enter/Space) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Enter and space will trigger a click event when using a <button> so would we end up with two events?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trade off with the above on managing disabled ourselves is that we need to hook into these events and manage disabled ourselves.
If we agree on how we treat disabled, then we'll need to abstract this somehow for all buttons.
| - Uses `SnapshotController` for state | ||
| - Uses `RequestController` for play/pause |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I simplified some of the controllers/hooks here, we'll just need Claude to re-run implementation plan.
I imagine we have to wait for #323 partially so we have feature accessors (e.g., getFeature(store)) before implementing this component. I'll create a PR tomorrow prob to get that smaller piece through so UI is unblocked.
| ### Registration | ||
|
|
||
| ```ts | ||
| customElements.define('media-play-button', PlayButtonElement); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth discussing with the team to confirm what prefix we're going with. I'll need to update existing Claude plans and what not to match.
Few arguments come to mind for vjs- over media-:
- You don't end up with funny names like
media-frosted-video-skin(media+video). - We used
media-in Media Chrome and Vidstack. Prevent collision with either. Look distinct too. vjsis iconic. I would recognize it instantly. It also popups when you inspect old player in class list.
Beyond that if the team decides media-, I'm down either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, I think I still prefer media- for it's more native, generic feeling.
I'm wondering now if we could pull off prefix-less if there are 2 or more words in the name.
Why not just play-button, time-slider?
With scoped registries on the horizon.
https://caniuse.com/wf-scoped-custom-element-registries
https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry
https://github.com/justinfagnani/webcomponents/blob/scoped-registries/proposals/Scoped-Custom-Element-Registries.md
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can only offer my opinion as a matter of taste. I don't really have any facts to bring to the table. But. Of the three options, I really like vjs-.
To me, using media- on media chrome felt like a branding exercise. "Web components are native HTML. They're timeless. Free from the constraints of component libraries. The media components you wish the platform had built in. Let's use timeless, platform-seeming names, too."
Meanwhile, from a brand standpoint, video.js 10 feels like more its own thing, rather than a thing of the platform. It has a bright brand on its website. It has an eye-catching skin. It demands that you learn the provider, the skin, and the media source. Everything about it feels opinionated. That just feels very vjs- to me.
MIND YOU. I haven't done truly native HTML dev in almost a decade. I don't know what naming conventions are idiomatic in web components. What's more important to me than a brand expression is idiomatic web component behavior. Good DX. If vjs- stands in the way of that, I take my opinion back. (And, maybe in the near future, scoped registries with generic names will be good DX. So. That's another potential wrench in my spiel.)
| function getPlayButtonProps(params: { | ||
| props: PlayButtonProps; | ||
| state: PlayButtonState; | ||
| onToggle: () => void; | ||
| }): PlayButtonDOMProps; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering if we should go a step further to simplify and just have getRootProps on core component class.
Similar to Zag.js, we can just define our own ElementProps in core (jsx), then map accordingly in html/react packages? Just a thought to co-locate more code and simplify.
| onPauseRequest?: () => void; | ||
| onPlay?: () => void; | ||
| onPause?: () => void; | ||
| onError?: (error: Error) => void; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't think of a reason for error handling at this level. Is there a clear one? If not I suggest we drop things we don't know we need.
|
Closing this one out as we're re-assigning work. I'll take the feedback from here and apply to internal design doc. |
fix #265
This pull request introduces a comprehensive implementation plan for the new
PlayButtonUI component, which will serve as a model for future UI components across the project. The plan details a multi-layered approach, covering core logic, DOM integration, React and HTML custom element implementations, and accessibility/testing requirements. Additionally, a minor fix is made to thecommitlintscript inpackage.json.Component architecture and implementation plan:
PlayButtoncomponent, outlining interfaces, implementation details, and file structure across the Core, DOM, React, and HTML packages. This plan establishes conventions for component state, props, event handling, accessibility, and testing. (.claude/plans/components/play-button.md)Accessibility and testing standards:
Development workflow improvement:
commitlintscript inpackage.jsonto remove the unused$1argument, ensuring consistent commit message linting. (package.json)