podcast-player icon indicating copy to clipboard operation
podcast-player copied to clipboard

Convert to Lit Element

Open davatron5000 opened this issue 3 years ago • 5 comments

Moving <podcast-player> over to LitElement. Most of the a11y stuff was done under the supervision of @feather for the ShopTalk Show site. But I have questions! And I'd like feedback! Specifically around the best way to allow passing necessary customizations and styling down to the component.

Work done so far.

  • [x] [DX] Convert to Lit Element
  • [x] [A11y] Convert progress to range input
  • [x] [A11y] Add A11y labels
  • [x] [Feature] Add TimeJump
  • [x] [Feature] Add 30s rewind and 30s ff
  • [x] [Feature] Add CSS grid-area properties for custom styling
  • [x] [API Change] Now requires a child <audio> element for progressively enhancing

Todo:

  • [ ] Move to package dependency, not unpkg
  • [ ] Add fucking build tools
  • [ ] Fix a few bugs where this.currentTime doesn't reset after the track has finished.
  • [ ] Add CSS variables for color theming
  • [ ] Fix hiccup in the input range smoothness

Questions:

  1. Is there a better way to allow custom styles? I've already added named grid-area properties, which might be a good hook
  2. Is there a better way to allow custom icons? There's a spritesheet with icons already, but I quickly imagine lots of situations where people would want to include their own custom icons.
  3. Is it possible to disable styles() entirely?

davatron5000 avatar Jan 20 '21 04:01 davatron5000

Is there a better way to allow custom icons? There's a spritesheet with icons already, but I quickly imagine lots of situations where people would want to include their own custom icons.

@davatron5000 -- not sure about the short term, but in the longer term the Personalization Semantics Content Module work is what you're looking for.

The data-action attribute is what holds promise for that type of customization. At least, that would provide a standard way of doing so for an END USER. You might be talking about a person implementing... In which case, it might make sense to leverage data-action as that would allow a hook for the implementer, but also an end user that wants to customize as well.

feather avatar Jan 20 '21 16:01 feather

There's been some interesting talk about the level of styling you can adopt in a pattern (regardless of implementation) lately and one path could be that you litter vend multiple levels. In that was you could ship PodcastPlayerBase with no styling, PodcastPlayer with basic styling, and then PodcastPlayerFancy etc with very custom styling. If you move customElements.define to another entry as outlined in https://open-wc.org/guides/developing-components/publishing/ users could then choose which they'd like to use and/or customize their own PodcastPlayerCustom from there. It's an interest concept, especially as far as scale of customizations go, and is somewhat similar to what you see in https://lion-web-components.netlify.app/?path=/story/forms-combobox-extensions--material-design, IIRC.

CSS Custom Properties are covering more controlled customizations. If you're not leveraging a "system", I worry that they can be pretty constraining. However, having the custom properties the base of the system like --podcast-player-rhythm and then use it to calculate things or --podcast-player-color-primary or --podcast-player-color-secondary etc. gives you a nice way to keep thins in that system. Ensuring that system aligns perfectly with the system outside of your element can sometimes cause friction. I know that the team behind Pattern Fly Elements spent a lot of time clarifying their property naming system to make the way you work a system of custom properties into a local customization of an element that is very nice. They document it pretty thoroughly in the "Notes" section of these stories: https://patternflyelements.com/storybook

On the surface of icons, I wonder if you can slot in a sprite sheet there? Likely not in the right DOM tree to be leveraged, but that would be quite cool. Using <slot><svg style="display: none;">...</svg></slot> so that a new slotted spite sheet could use the same icon names and customize their delivery would be so cool, please check that out and write it up if it actually works!! Otherwise, you could do something like the following for more explicit control:

<button class="button-mute" aria-label="Mute"  style="grid-area: mute" @click="${this.mute}">
          <slot name="unmuted-icon"><svg class="unmuted">
            <use xlink:href="#icon-speaker-unmuted"></use>
          </svg></slot>
          <slot name="muted-icon"><svg class="muted"><use xlink:href="#icon-speaker-muted"></use></svg></slot>
        </button>

It feels heavy to need to do each of these very directly, and positions you to need to do so many icons individually, which might not be fun for consumer. Though if you could slot a sprit sheet and then slot a <use xlink:href="#icon-speaker-unmuted"></use> would be very interesting, e.g. : <svg class="muted"><slot name="muted-icon"><use xlink:href="#icon-speaker-muted"></use></slot></svg> so that consumers could also be customizing the icons refs...

The one piece here that you've not brought up is the possibility to use CSS Parts. In that way you could skip local styles and then require consumers to fully style specific parts of the element from the outside, like you see with pseudo elements in form controls natively. In that was you could surface the 9 or so elements that users might want to control (play, pause, rewind, fast forward, time, range, duration, speed, unmute, mute, etc) or less, as some of these might not need full control for users to take control of each other these things on their own.

So many options, which is maybe the bigger problem here, sorry to drop so many non-answers on you. Happy to chat some more as you continue to finalize your decisions on this.

Westbrook avatar Jan 20 '21 19:01 Westbrook

To start off: Nice port!

I'm not too shabby with a11y and customizability, but I'll share a small change that I think could ease the code a bit:

You could use LitElement's provided ability to reflect properties to attributes, and control the playing and muted -statuses that way.

I created a fork with just that functionality, if you want to check it out, and consider it.

https://github.com/Matsuuu/podcast-player/commit/2b315e2d3e6bc47972ddd396854abeb67ee95f72

Matsuuu avatar Jan 20 '21 20:01 Matsuuu

@Matsuuu This looks great! If you want to PR against this branch, I can merge in.

@Westbrook Thanks for the feedback. I ❤️ the spritesheet slot idea. I'm going to take a stab at that. And if that works, then try the custom <use> slot. But the spritesheet slot gets things pretty far probably.

@feather First time hearing about Personalization Semantics. But should be easy to layer in. Is there any AT out there that has this yet to QA against whether or not I did it right?

davatron5000 avatar Jan 20 '21 21:01 davatron5000

@feather First time hearing about Personalization Semantics. But should be easy to layer in. Is there any AT out there that has this yet to QA against whether or not I did it right?

Not really, no 🙂 This is from work in progress and isn’t likely on the radar of any AT vendor yet, and the main use case will be people that create custom browser extensions/user styles for their own use. Think “I want all the search buttons that I ever see on any web page to use a set of binoculars instead of a magnifying glass” and “I want to make all rewind and ffwd buttons look like this << >> instead of the round arrow circley ones we see everywhere”

So nothing to do right quite yet - just wanted them to be on your radar so that you could plan for that eventuality... no reason not to adopt their naming conventions as you implement.

feather avatar Jan 21 '21 04:01 feather