Files
webawesome/src/components/button-group/button-group.ts

86 lines
2.6 KiB
TypeScript
Raw Normal View History

2021-07-09 20:45:44 -04:00
import { LitElement, html } from 'lit';
2021-05-27 17:00:43 -04:00
import { customElement, property, query } from 'lit/decorators.js';
2021-07-09 20:45:44 -04:00
import styles from './button-group.styles';
2020-08-06 09:07:24 -04:00
/**
* @since 2.0
* @status stable
*
2021-06-25 16:25:46 -04:00
* @slot - One or more `<sl-button>` elements to display in the button group.
2020-08-06 09:07:24 -04:00
*
2021-06-25 16:25:46 -04:00
* @csspart base - The component's base wrapper.
2020-08-06 09:07:24 -04:00
*/
2021-03-18 09:04:23 -04:00
@customElement('sl-button-group')
2021-03-08 19:14:32 -05:00
export default class SlButtonGroup extends LitElement {
2021-07-09 20:45:44 -04:00
static styles = styles;
2020-08-06 09:07:24 -04:00
@query('slot') defaultSlot: HTMLSlotElement;
2020-09-04 17:11:25 -04:00
/** A label to use for the button group's `aria-label` attribute. */
2021-06-30 20:04:46 -04:00
@property() label = '';
2020-08-06 09:07:24 -04:00
handleFocus(event: CustomEvent) {
const button = findButton(event.target as HTMLElement);
button?.classList.add('sl-button-group__button--focus');
2020-08-06 09:07:24 -04:00
}
handleBlur(event: CustomEvent) {
const button = findButton(event.target as HTMLElement);
button?.classList.remove('sl-button-group__button--focus');
}
handleMouseOver(event: CustomEvent) {
const button = findButton(event.target as HTMLElement);
button?.classList.add('sl-button-group__button--hover');
}
handleMouseOut(event: CustomEvent) {
const button = findButton(event.target as HTMLElement);
button?.classList.remove('sl-button-group__button--hover');
}
handleSlotChange() {
const slottedElements = [...this.defaultSlot.assignedElements({ flatten: true })] as HTMLElement[];
slottedElements.forEach(el => {
const index = slottedElements.indexOf(el);
const button = findButton(el);
if (button !== null) {
button.classList.add('sl-button-group__button');
button.classList.toggle('sl-button-group__button--first', index === 0);
button.classList.toggle('sl-button-group__button--inner', index > 0 && index < slottedElements.length - 1);
button.classList.toggle('sl-button-group__button--last', index === slottedElements.length - 1);
}
});
2020-08-06 09:07:24 -04:00
}
render() {
// eslint-disable-next-line lit-a11y/mouse-events-have-key-events -- focusout & focusin support bubbling where as focus & blur do not which is necessary here
2021-02-26 09:09:13 -05:00
return html`
<div
part="base"
class="button-group"
2021-04-01 07:50:27 -04:00
role="group"
2021-02-26 09:09:13 -05:00
aria-label=${this.label}
2021-03-06 12:01:39 -05:00
@focusout=${this.handleBlur}
@focusin=${this.handleFocus}
@mouseover=${this.handleMouseOver}
@mouseout=${this.handleMouseOut}
2021-02-26 09:09:13 -05:00
>
<slot @slotchange=${this.handleSlotChange}></slot>
2020-08-06 09:07:24 -04:00
</div>
2021-02-26 09:09:13 -05:00
`;
2020-08-06 09:07:24 -04:00
}
}
function findButton(el: HTMLElement) {
return el.tagName.toLowerCase() === 'sl-button' ? el : el.querySelector('sl-button');
}
2021-03-12 09:09:08 -05:00
declare global {
interface HTMLElementTagNameMap {
'sl-button-group': SlButtonGroup;
}
}