-
Notifications
You must be signed in to change notification settings - Fork 82
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
Theme architecture proposal #42
Conversation
This pull request is being automatically deployed with Vercel (learn more). 🔍 Inspect: https://vercel.com/mux/media-chrome/J2FjGjWfiPwtW8QQBntmp1jcgrNG |
themes/media-theme-netflix.js
Outdated
|
||
<media-controller> | ||
|
||
<slot name="media" slot="media"></slot> |
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.
This is the thing that feels nuckin futs. Chaining slots. But it works!
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.
Whoa.
So from the outside, an application does this:
<media-theme-netflix>
<video slot="media"></video>
</media-theme-netflix>
That "media" slot gets passed through into the "media" slot for media-controller
. Pretty nuckin futs
@dylanjha @mmcc @cjpillsbury Speak up if you have an opinion on this, otherwise I'm gonna move forward with it. |
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'm in favor of this approach with <media-theme-xxx>
elements. Easy to understand what's going on and each of the <media-theme-xxx>
themes provide a great example.
The one question I have is:
- What about in this Netflix example when the theme contains other variables like
videoTitle
? -- Would themedia-theme-netflix
specify other attributes like<media-theme-netflix video-title="Breaking Bad" video-episode="Episode 2">
themes/media-theme-netflix.js
Outdated
|
||
<media-controller> | ||
|
||
<slot name="media" slot="media"></slot> |
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.
Whoa.
So from the outside, an application does this:
<media-theme-netflix>
<video slot="media"></video>
</media-theme-netflix>
That "media" slot gets passed through into the "media" slot for media-controller
. Pretty nuckin futs
Good call that this needs to be clear as part of this. Slots are the first answer for me. Themes may have lots of use cases for embedding custom content, and using attributes might feel overloaded. Slots are a custom element's answer to content "variables". And compared to attributes, updates to the slot contents are automatically handled. <media-theme-abc>
<video slot="media"></video>
<span slot="media-title">My great title</span>
</media-theme-abc> A second answer for things like title specifically is potentially defining media metadata elements inside a media element. I think I mentioned this in another issue somewhere. <media-theme-abc>
<video slot="media">
<media-metadata-title>My great title</media-metadata-title>
</video>
</media-theme-abc> With that, if you swap the video, for example as part of playlist, the metadata comes/goes with it. Doesn't even need to be a real custom element, I think. A downside is handling changes to those elements. Might require yet more mutation observers. But upside is it's compatible with the native audio/video elements, which hide that content by default but still make it available to javascript. So it might end up being both. For example, the Does that make sense? Any thoughts or ideas on that? |
@heff I love using slots for this. I'm on board with the idea that any particular "theme" like |
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.
mostly nits.
document[fullscreenApi.exit](); | ||
|
||
// Shadow root throws an error for this function | ||
// this.getRootNode()[fullscreenApi.exit](); |
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.
Do we know why we were using this.getRootNode()
here originally? will this work for iframe embeds? Noticed we were using getRootNode()
in several places. If this is safe, should we be changing it in other locations as well?
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.
It seems like it's gonna be context specific, depending on if we need the shadowRoot when that's the element's context and if it supports the needed APIs.
themes/example.html
Outdated
</media-theme-netflix> | ||
|
||
</body> | ||
</html> |
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: missing newline for EOF
themes/example.html
Outdated
@@ -0,0 +1,18 @@ | |||
<html> |
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: We should probably keep "examples" separate from "source"
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.
👍
themes/media-theme-netflix.js
Outdated
@@ -0,0 +1,164 @@ | |||
import MediaTheme from './media-theme.js'; |
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.
Fine for now, but there are several inconsistencies with the current browser-based netflix player. Should make followup issue(s) to clean up. Also may want to consider splitting out the part that sizes this to full width from the rest of the theme.
themes/media-theme-netflix.js
Outdated
|
||
class MediaThemeNetflix extends MediaTheme { | ||
constructor(options={}) { | ||
options = Object.assign({ |
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: no need to mutate options
(may cause unexpected side effects for implementors). consider instead simply inline object spread, a la:
super(template, { /* allow ...defaultOptions, */ ...options });
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.
How is options
getting mutated? Either way I'm good with the spread.
themes/media-theme.js
Outdated
constructor(template=``, options={}) { | ||
super(); | ||
|
||
options = Object.assign({ |
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.
see comment ☝️
let media = this.querySelector(':scope > [slot=media]'); | ||
|
||
// Chaining media slots for media templates | ||
if (media.nodeName == 'SLOT') media = media.assignedElements({flatten:true})[0]; |
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.
Fine for now. May be some weird edge cases that are missed, but we can file followup issues if/when they show up and are a priority.
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.
Such a pessimist. :) It's like you've had to work in the browser before or something.
Cleaned up and finally merging in. |
yooooo 🙌🏼 🎉 |
I was thinking through how we might host and load themes, and I landed on using custom elements to do it.
Custom elements:
Hoping to get feedback.
I see two ways they might be used.
1. Used directly in the HTML
2. Access the template string to clone into the shadow dom of a wrapping player
Video player constructor