ember-a11y-dropdown
This is an accessible dropdown that you can use in your Ember app for a menu dropdown. I'm making it so people can stop using the <details>
element because that's really a nested interactive element.
Whatever else you may be able to force this component to do is coincidental.
Compatibility
- Ember.js v3.20 or above
- Ember CLI v3.20 or above
- Node.js v12 or above
Installation
I haven't released this addon yet, but once I do you can install it the same way you do other Ember addons:
ember install ember-a11y-dropdown
Usage
The component markup:
- a div to wrap the entire component so it doesn't mess up your flex or grid layout
- a button element to show/hide the dropdown
- an unordered list element that contains the dropdown
- the LinkTo components (link element) if a route is defined
Classes for styling:
The specificity in the addon is a single level; it is explicitly only the class names that are attached to each element of the component. That means if you want to override on your own, you can.
- the wrapping
<div>
has the classea-dropdown
- the
<button>
has the classea-dropdown__button
- the
<ul>
has the classea-dropdown__list
- the
<li>
has the classea-dropdown__list-item
- the
<a>
has the classea-dropdown__link
Now, if you are going to override any borders or outlines, do it the accessible way!
.my-element {
border-color: transparent;
}
With a transparent border, users with high-contrast mode will still be able to see borders because high-contrast mode ignores border colors. Pretty cool trick, right?
Basic use:
The most basic use of the component requires a listItems
array to be passed. You can do this with Ember's built-in array
helper if you want:
This will result in a button labeled "menu" and when interacted with, will show an unordered list with the array items in a list.
You can also add an array to a controller for the page where you've used the component:
For example, here's the controller in this addon's demo app:
// controllers/application.js
import Controller from '@ember/controller';
import { tracked } from '@glimmer/tracking';
export default class ApplicationController extends Controller {
@tracked someArray = [
{
route: 'index',
name: 'one',
},
{
route: 'alpha', // actual name of route in demo app
name: 'two',
},
];
}
And here it is invoked in the demo app's application template:
Of course, it's far more likely that you'll use this as part of your header or nav component. In this example, I've made a component in the demo app called ea-header-demo
and used the dropdown component inside of that:
This means that I can define the array for @listItems
in my component instead of a controller:
// tests/dummy/app/components/ea-header-demo.js
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
export default class EaHeaderDemoComponent extends Component {
@tracked listItems = [
{
route: 'index',
name: 'Home',
},
{
route: 'alpha',
name: 'Alpha Page',
},
];
}
Contributing
File an issue if you think something is missing or should be added.
PRs to fix those issues are welcome.
Feel free to ping me on Discord if I don't reply soon enough (and sorry in advance if that happens).
License
This project is licensed under the MIT License.