This approach uses a input attribute accepting an array of items. The control over the list markup is with the component and accessibility can be guaranteed. Still, there is a possibility to customize the list item template in a general way. A possible implementation could look like this: https://lit.dev/playground/#gist=78bf6997e7ecf38d8d981f66d7e3f472.
Custom list item template implementation
A slot might not be best suited for this use case, therefore an external reference could make more sense.
++ Simple implementation
++ Items are passed via JS API in most cases anyway
++ Full control over list items from within web component
-- Limited possibility to define custom template, just one template for all items. A language selector dropdown with custom flag icons for every language would not be possible (easily)
-- Needs JS to render items
Option 2: User defined list of items
Another approach for supporting custom templates could be to take a list of links as slotted content instead of an array of items as property.
++ Items are defined with standard markup and fully customizable, a language selection with custom flag icons would easily be possible
++ Items are available before JS loads (when not rendered client side)
-- Limited control over slotted items from within web component, their state could change any moment
-- Implementation has to listen to slot changes in order to register correct event handlers
Option 3
There is also the possibility to split up the component into smaller parts in order to give more flexibility as to the contents of each element.
++ Maximum content flexibility
-- More complicated interaction between components from component perspective (quagmire of slots)
-- More markup required
-- Implementation has to listen to slot changes in order to register correct event handlers
Option 4
Following the headless-ui listbox example, a third component is used for rendering the links. This gives control over the links back to the library authors.
++ Good content flexibility
++ Control over important elements is with the library author
-- More markup required
-- Implementation has to listen to slot changes in order to register correct event handlers
Edge cases
The dropdown list should never be hidden by page boundaries. If the action menu button is placed directly at the edge of the screen, the dropdown list should adapt its alignment. Default alignment is bottom left.
There might be content before or after the link list
There might be cateogries of links or grouped link lists
Examples of possible use cases
Language switch
Breadcrumbs on mobile
Login widgetMight not be ideal because when using aria-activedescendant, the additional content in the dropdown header might not be accessible or skipped by assistive tech.
Create an action menu button. This button shows a dropdown with a list of links on click and offers various ways to browse that list.
https://next.design-system.post.ch/?path=/story/components-internet-header-header--default (does not fulfill accessibility requirements)
Proposed API
In order to provide flexibility to the list item template, there are (at least) two options:
Option 1: Custom template for list items
This approach uses a input attribute accepting an array of items. The control over the list markup is with the component and accessibility can be guaranteed. Still, there is a possibility to customize the list item template in a general way. A possible implementation could look like this: https://lit.dev/playground/#gist=78bf6997e7ecf38d8d981f66d7e3f472.
Custom list item template implementation
A slot might not be best suited for this use case, therefore an external reference could make more sense.
++ Simple implementation ++ Items are passed via JS API in most cases anyway ++ Full control over list items from within web component -- Limited possibility to define custom template, just one template for all items. A language selector dropdown with custom flag icons for every language would not be possible (easily) -- Needs JS to render items
Option 2: User defined list of items
Another approach for supporting custom templates could be to take a list of links as slotted content instead of an array of items as property.
Test implementation (WIP): https://lit.dev/playground/#gist=212821f67bab636ff2d53552251373e7
++ Items are defined with standard markup and fully customizable, a language selection with custom flag icons would easily be possible ++ Items are available before JS loads (when not rendered client side) -- Limited control over slotted items from within web component, their state could change any moment -- Implementation has to listen to slot changes in order to register correct event handlers
Option 3
There is also the possibility to split up the component into smaller parts in order to give more flexibility as to the contents of each element.
++ Maximum content flexibility -- More complicated interaction between components from component perspective (quagmire of slots) -- More markup required -- Implementation has to listen to slot changes in order to register correct event handlers
Option 4
Following the headless-ui listbox example, a third component is used for rendering the links. This gives control over the links back to the library authors.
++ Good content flexibility ++ Control over important elements is with the library author -- More markup required -- Implementation has to listen to slot changes in order to register correct event handlers
Edge cases
Examples of possible use cases
Language switch
Breadcrumbs on mobile
Login widget Might not be ideal because when using
aria-activedescendant
, the additional content in the dropdown header might not be accessible or skipped by assistive tech.