Skip to content

Commit 020ce66

Browse files
committed
refactor(chip): Use SlotController and ARIA fixes
1 parent 676fff9 commit 020ce66

File tree

1 file changed

+74
-70
lines changed

1 file changed

+74
-70
lines changed

src/components/chip/chip.ts

Lines changed: 74 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import { html, LitElement, nothing } from 'lit';
2-
import { property, queryAssignedElements } from 'lit/decorators.js';
3-
import { createRef, type Ref, ref } from 'lit/directives/ref.js';
4-
2+
import { property } from 'lit/decorators.js';
3+
import { createRef, ref } from 'lit/directives/ref.js';
54
import { addThemingController } from '../../theming/theming-controller.js';
65
import { addKeybindings } from '../common/controllers/key-bindings.js';
6+
import { addSlotController, setSlots } from '../common/controllers/slot.js';
77
import { registerComponent } from '../common/definitions/register.js';
88
import type { Constructor } from '../common/mixins/constructor.js';
99
import { EventEmitterMixin } from '../common/mixins/event-emitter.js';
10-
import { isEmpty } from '../common/util.js';
1110
import IgcIconComponent from '../icon/icon.js';
1211
import type { StyleVariant } from '../types.js';
1312
import { styles } from './themes/chip.base.css.js';
@@ -42,11 +41,15 @@ export default class IgcChipComponent extends EventEmitterMixin<
4241
public static styles = [styles, shared];
4342

4443
/* blazorSuppress */
45-
public static register() {
44+
public static register(): void {
4645
registerComponent(IgcChipComponent, IgcIconComponent);
4746
}
4847

49-
private _removePartRef: Ref<HTMLSlotElement> = createRef();
48+
private readonly _removePartRef = createRef<HTMLSlotElement>();
49+
50+
private readonly _slots = addSlotController(this, {
51+
slots: setSlots('prefix', 'suffix', 'start', 'end', 'select', 'remove'),
52+
});
5053

5154
/**
5255
* Sets the disabled state for the chip.
@@ -84,18 +87,6 @@ export default class IgcChipComponent extends EventEmitterMixin<
8487
@property({ reflect: true })
8588
public variant!: StyleVariant;
8689

87-
@queryAssignedElements({ slot: 'prefix' })
88-
protected prefixes!: Array<HTMLElement>;
89-
90-
@queryAssignedElements({ slot: 'start' })
91-
protected contentStart!: Array<HTMLElement>;
92-
93-
@queryAssignedElements({ slot: 'suffix' })
94-
protected suffixes!: Array<HTMLElement>;
95-
96-
@queryAssignedElements({ slot: 'end' })
97-
protected contentEnd!: Array<HTMLElement>;
98-
9990
constructor() {
10091
super();
10192

@@ -104,75 +95,88 @@ export default class IgcChipComponent extends EventEmitterMixin<
10495
addKeybindings(this, {
10596
ref: this._removePartRef,
10697
bindingDefaults: { triggers: ['keyup'] },
107-
}).setActivateHandler(this.handleRemove);
98+
}).setActivateHandler(this._handleRemove);
10899
}
109100

110-
protected override createRenderRoot() {
111-
const root = super.createRenderRoot();
112-
root.addEventListener('slotchange', () => this.requestUpdate());
113-
return root;
114-
}
115-
116-
protected handleSelect() {
101+
protected _handleSelect(): void {
117102
if (this.selectable) {
118103
this.selected = !this.selected;
119104
this.emitEvent('igcSelect', { detail: this.selected });
120105
}
121106
}
122107

123-
protected handleRemove(e: Event) {
108+
protected _handleRemove(event: Event): void {
109+
event.stopPropagation();
124110
this.emitEvent('igcRemove');
125-
e.stopPropagation();
111+
}
112+
113+
protected _renderPrefix() {
114+
const isVisible =
115+
this._slots.hasAssignedElements('prefix') ||
116+
this._slots.hasAssignedElements('start');
117+
118+
const selectSlot =
119+
this.selectable && this.selected
120+
? html`
121+
<slot name="select">
122+
<igc-icon name="selected" collection="default"></igc-icon>
123+
</slot>
124+
`
125+
: nothing;
126+
127+
return html`
128+
<span part="prefix" ?hidden=${!isVisible && !this.selected}>
129+
${selectSlot}
130+
<slot name="start"></slot>
131+
<slot name="prefix"></slot>
132+
</span>
133+
`;
134+
}
135+
136+
protected _renderSuffix() {
137+
const isVisible =
138+
this._slots.hasAssignedElements('suffix') ||
139+
this._slots.hasAssignedElements('end');
140+
141+
const removeSlot =
142+
this.removable && !this.disabled
143+
? html`
144+
<slot
145+
${ref(this._removePartRef)}
146+
name="remove"
147+
@click=${this._handleRemove}
148+
>
149+
<igc-icon
150+
name="remove"
151+
collection="default"
152+
tabindex="0"
153+
role="button"
154+
aria-label="Remove"
155+
></igc-icon>
156+
</slot>
157+
`
158+
: nothing;
159+
160+
return html`
161+
<span part="suffix" ?hidden=${!isVisible && !this.removable}>
162+
<slot name="end"></slot>
163+
<slot name="suffix"></slot>
164+
${removeSlot}
165+
</span>
166+
`;
126167
}
127168

128169
protected override render() {
129170
return html`
130171
<button
131172
part="base"
132-
.disabled=${this.disabled}
133-
aria-selected=${this.selected}
134-
aria-disabled=${this.disabled}
135-
@click=${this.handleSelect}
173+
.ariaPressed=${this.selectable ? this.selected.toString() : null}
174+
?disabled=${this.disabled}
175+
@click=${this._handleSelect}
136176
>
137-
<span
138-
part="prefix"
139-
.hidden=${isEmpty(this.prefixes) &&
140-
isEmpty(this.contentStart) &&
141-
!this.selected}
142-
>
143-
${this.selectable && this.selected
144-
? html`<slot name="select">
145-
<igc-icon name="selected" collection="default"></igc-icon>
146-
</slot>`
147-
: nothing}
148-
<slot name="start"></slot>
149-
<slot name="prefix"></slot>
150-
</span>
177+
${this._renderPrefix()}
151178
<slot></slot>
152-
<span
153-
part="suffix"
154-
.hidden=${isEmpty(this.suffixes) &&
155-
isEmpty(this.contentEnd) &&
156-
!this.removable}
157-
>
158-
<slot name="end"></slot>
159-
<slot name="suffix"></slot>
160-
${this.removable && !this.disabled
161-
? html`<slot
162-
${ref(this._removePartRef)}
163-
@click=${this.handleRemove}
164-
name="remove"
165-
>
166-
<igc-icon
167-
name="remove"
168-
collection="default"
169-
tabindex="0"
170-
role="button"
171-
aria-label="remove"
172-
></igc-icon>
173-
</slot>`
174-
: nothing}
175-
</span>
179+
${this._renderSuffix()}
176180
</button>
177181
`;
178182
}

0 commit comments

Comments
 (0)