Skip to content

Commit a7fa8e0

Browse files
committed
Fix missing focus after removing a tag
1 parent 1603ff3 commit a7fa8e0

File tree

3 files changed

+43
-2
lines changed

3 files changed

+43
-2
lines changed

.changeset/thirty-ducks-walk.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@sl-design-system/tag': patch
3+
---
4+
5+
Fix missing focus after removing a tag
6+
7+
This set's the focus to the tag before the removed tag, or the next tag if the removed tag was the first one.

packages/components/tag/src/tag-list.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { fixture } from '@sl-design-system/vitest-browser-lit';
2+
import { userEvent } from '@vitest/browser/context';
23
import { html } from 'lit';
34
import { beforeEach, describe, expect, it } from 'vitest';
45
import '../register.js';
@@ -60,6 +61,27 @@ describe('sl-tag', () => {
6061
});
6162
});
6263

64+
describe('removable', () => {
65+
beforeEach(async () => {
66+
el = await fixture(html`
67+
<sl-tag-list>
68+
<sl-tag removable>My label 1</sl-tag>
69+
<sl-tag removable>My label 2</sl-tag>
70+
<sl-tag removable>My label 3</sl-tag>
71+
</sl-tag-list>
72+
`);
73+
});
74+
75+
it('should focus the previous tag when a tag is removed', async () => {
76+
const tags = Array.from(el.querySelectorAll('sl-tag'));
77+
78+
tags.at(-1)?.focus();
79+
await userEvent.keyboard('{Backspace}');
80+
81+
expect(document.activeElement).to.equal(tags.at(-2));
82+
});
83+
});
84+
6385
describe('stacked', () => {
6486
beforeEach(async () => {
6587
el = await fixture(html`

packages/components/tag/src/tag-list.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { type CSSResultGroup, LitElement, type PropertyValues, type TemplateResu
66
import { property, query, state } from 'lit/decorators.js';
77
import { ifDefined } from 'lit/directives/if-defined.js';
88
import styles from './tag-list.scss.js';
9-
import { Tag, type TagSize, type TagVariant } from './tag.js';
9+
import { type SlRemoveEvent, Tag, type TagSize, type TagVariant } from './tag.js';
1010

1111
declare global {
1212
interface HTMLElementTagNameMap {
@@ -159,12 +159,24 @@ export class TagList extends ScopedElementsMixin(LitElement) {
159159
</div>
160160
`
161161
: nothing}
162-
<div class="list">
162+
<div @sl-remove=${this.#onRemove} class="list">
163163
<slot @slotchange=${this.#onSlotChange}></slot>
164164
</div>
165165
`;
166166
}
167167

168+
#onRemove(event: SlRemoveEvent & { target: Tag }): void {
169+
console.log('remove', event.target);
170+
171+
const index = this.#rovingTabindexController.elements.indexOf(event.target as Tag);
172+
173+
console.log({ index });
174+
175+
this.#rovingTabindexController.focusToElement(index + (index === 0 ? 1 : -1));
176+
177+
console.log('after remove');
178+
}
179+
168180
#onResize(entries: ResizeObserverEntry[]): void {
169181
const stackEntry = entries.find(entry => entry.target === this.stack),
170182
stackInlineSize = stackEntry?.contentRect.width;

0 commit comments

Comments
 (0)