/**
* @license
* Copyright 2023 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import '../../elevation/elevation.js';
import {html, nothing} from 'lit';
import {property, query} from 'lit/decorators.js';
import {ARIAMixinStrict} from '../../internal/aria/aria.js';
import {redispatchEvent} from '../../internal/events/redispatch-event.js';
import {MultiActionChip} from './multi-action-chip.js';
import {renderRemoveButton} from './trailing-icons.js';
/**
* A filter chip component.
*
* @fires remove {Event} Dispatched when the remove button is clicked.
*/
export class FilterChip extends MultiActionChip {
@property({type: Boolean}) elevated = false;
@property({type: Boolean}) removable = false;
@property({type: Boolean, reflect: true}) selected = false;
/**
* Only needed for SSR.
*
* Add this attribute when a filter chip has a `slot="selected-icon"` to avoid
* a Flash Of Unstyled Content.
*/
@property({type: Boolean, reflect: true, attribute: 'has-selected-icon'})
hasSelectedIcon = false;
protected get primaryId() {
return 'button';
}
@query('.primary.action')
protected readonly primaryAction!: HTMLElement | null;
@query('.trailing.action')
protected readonly trailingAction!: HTMLElement | null;
protected override getContainerClasses() {
return {
...super.getContainerClasses(),
elevated: this.elevated,
selected: this.selected,
'has-trailing': this.removable,
'has-icon': this.hasIcon || this.selected,
};
}
protected override renderPrimaryAction(content: unknown) {
const {ariaLabel} = this as ARIAMixinStrict;
return html`
`;
}
protected override renderLeadingIcon() {
if (!this.selected) {
return super.renderLeadingIcon();
}
return html`
`;
}
protected override renderTrailingAction(focusListener: EventListener) {
if (this.removable) {
return renderRemoveButton({
focusListener,
ariaLabel: this.ariaLabelRemove,
disabled: this.disabled || this.softDisabled,
});
}
return nothing;
}
protected override renderOutline() {
if (this.elevated) {
return html``;
}
return super.renderOutline();
}
private handleClickOnChild(event: MouseEvent) {
if (this.disabled || this.softDisabled) {
return;
}
// Store prevValue to revert in case `chip.selected` is changed during an
// event listener.
const prevValue = this.selected;
this.selected = !this.selected;
const preventDefault = !redispatchEvent(this, event);
if (preventDefault) {
// We should not do `this.selected = !this.selected`, since a client
// click listener could change its value. Instead, always revert to the
// original value.
this.selected = prevValue;
return;
}
}
}