Skip to content

Commit 79da0fa

Browse files
authored
refactor: update tabindex logic to work with Lit, add sync: true (#9119)
1 parent 97c5b5e commit 79da0fa

File tree

4 files changed

+77
-53
lines changed

4 files changed

+77
-53
lines changed

packages/a11y-base/src/delegate-focus-mixin.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export const DelegateFocusMixin = dedupeMixin(
4242
type: Object,
4343
readOnly: true,
4444
observer: '_focusElementChanged',
45+
sync: true,
4546
},
4647

4748
/**
@@ -228,6 +229,11 @@ export const DelegateFocusMixin = dedupeMixin(
228229
}
229230
this.tabindex = undefined;
230231
}
232+
233+
// Lit does not remove attribute when setting property to undefined
234+
if (tabindex === undefined && this.hasAttribute('tabindex')) {
235+
this.removeAttribute('tabindex');
236+
}
231237
}
232238
},
233239
);

packages/a11y-base/src/tabindex-mixin.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export const TabindexMixin = (superclass) =>
2727
type: Number,
2828
reflectToAttribute: true,
2929
observer: '_tabindexChanged',
30+
sync: true,
3031
},
3132

3233
/**
@@ -60,9 +61,13 @@ export const TabindexMixin = (superclass) =>
6061
if (this.tabindex !== undefined) {
6162
this._lastTabIndex = this.tabindex;
6263
}
63-
this.tabindex = -1;
64+
this.setAttribute('tabindex', '-1');
6465
} else if (oldDisabled) {
65-
this.tabindex = this._lastTabIndex;
66+
if (this._lastTabIndex !== undefined) {
67+
this.setAttribute('tabindex', this._lastTabIndex);
68+
} else {
69+
this.tabindex = undefined;
70+
}
6671
}
6772
}
6873

@@ -80,7 +85,7 @@ export const TabindexMixin = (superclass) =>
8085

8186
if (this.disabled && tabindex !== -1) {
8287
this._lastTabIndex = tabindex;
83-
this.tabindex = -1;
88+
this.setAttribute('tabindex', '-1');
8489
}
8590
}
8691

packages/a11y-base/test/delegate-focus-mixin.test.js

Lines changed: 44 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,46 @@
11
import { expect } from '@vaadin/chai-plugins';
2-
import { fixtureSync, focusin, focusout, nextFrame } from '@vaadin/testing-helpers';
2+
import { defineLit, definePolymer, fixtureSync, focusin, focusout, nextFrame } from '@vaadin/testing-helpers';
33
import sinon from 'sinon';
4-
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
4+
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
5+
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
56
import { DelegateFocusMixin } from '../src/delegate-focus-mixin.js';
67

7-
describe('delegate-focus-mixin', () => {
8-
let element, input, setFocusedSpy;
9-
10-
customElements.define(
11-
'delegate-focus-mixin-element',
12-
class extends DelegateFocusMixin(PolymerElement) {
13-
static get template() {
14-
return html`
15-
<slot name="input"></slot>
16-
<slot name="suffix"></slot>
17-
`;
18-
}
19-
20-
/** @protected */
21-
ready() {
22-
super.ready();
23-
24-
const input = this.querySelector('input');
25-
this._setFocusElement(input);
26-
}
27-
28-
_setFocused(focused) {
29-
super._setFocused(focused);
30-
setFocusedSpy?.(focused);
31-
}
32-
},
8+
const runTests = (defineHelper, baseMixin) => {
9+
let setFocusedSpy;
10+
11+
const tag = defineHelper(
12+
'delegate-focus-mixin',
13+
`
14+
<slot name="input"></slot>
15+
<slot name="suffix"></slot>
16+
`,
17+
(Base) =>
18+
class extends DelegateFocusMixin(baseMixin(Base)) {
19+
ready() {
20+
super.ready();
21+
const input = this.querySelector('input');
22+
this._setFocusElement(input);
23+
}
24+
25+
_setFocused(focused) {
26+
super._setFocused(focused);
27+
setFocusedSpy?.(focused);
28+
}
29+
},
3330
);
3431

32+
let element, input;
33+
3534
describe('default', () => {
3635
let button;
3736

3837
beforeEach(() => {
3938
setFocusedSpy = sinon.spy();
4039
element = fixtureSync(`
41-
<delegate-focus-mixin-element>
40+
<${tag}>
4241
<input slot="input" />
4342
<button slot="suffix"></button>
44-
</delegate-focus-mixin-element>
43+
</${tag}>
4544
`);
4645
input = element.querySelector('input');
4746
button = element.querySelector('button');
@@ -143,9 +142,9 @@ describe('delegate-focus-mixin', () => {
143142

144143
beforeEach(() => {
145144
element = fixtureSync(`
146-
<delegate-focus-mixin-element>
145+
<${tag}>
147146
<input slot="input" />
148-
</delegate-focus-mixin-element>
147+
</${tag}>
149148
`);
150149
input = element.querySelector('input');
151150
spy = sinon.spy();
@@ -188,7 +187,7 @@ describe('delegate-focus-mixin', () => {
188187

189188
describe('autofocus', () => {
190189
beforeEach(() => {
191-
element = document.createElement('delegate-focus-mixin-element');
190+
element = document.createElement(tag);
192191
element.autofocus = true;
193192

194193
const input = document.createElement('input');
@@ -246,9 +245,9 @@ describe('delegate-focus-mixin', () => {
246245
describe('default', () => {
247246
beforeEach(() => {
248247
element = fixtureSync(`
249-
<delegate-focus-mixin-element>
248+
<${tag}>
250249
<input slot="input" />
251-
</delegate-focus-mixin-element>
250+
</${tag}>
252251
`);
253252
input = element.querySelector('input');
254253
});
@@ -285,9 +284,9 @@ describe('delegate-focus-mixin', () => {
285284
describe('attribute', () => {
286285
beforeEach(() => {
287286
element = fixtureSync(`
288-
<delegate-focus-mixin-element tabindex="-1">
287+
<${tag} tabindex="-1">
289288
<input slot="input" />
290-
</delegate-focus-mixin-element>
289+
</${tag}>
291290
`);
292291
input = element.querySelector('input');
293292
});
@@ -307,4 +306,12 @@ describe('delegate-focus-mixin', () => {
307306
});
308307
});
309308
});
309+
};
310+
311+
describe('DelegateFocusMixin + Polymer', () => {
312+
runTests(definePolymer, ControllerMixin);
313+
});
314+
315+
describe('DelegateFocusMixin + Lit', () => {
316+
runTests(defineLit, PolylitMixin);
310317
});

packages/a11y-base/test/tabindex-mixin.test.js

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
11
import { expect } from '@vaadin/chai-plugins';
2-
import { fixtureSync } from '@vaadin/testing-helpers';
3-
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
2+
import { defineLit, definePolymer, fixtureSync } from '@vaadin/testing-helpers';
3+
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
4+
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
45
import { TabindexMixin } from '../src/tabindex-mixin.js';
56

6-
customElements.define(
7-
'tabindex-mixin-element',
8-
class extends TabindexMixin(PolymerElement) {
9-
static get template() {
10-
return html`<div></div>`;
11-
}
12-
},
13-
);
7+
const runTests = (defineHelper, baseMixin) => {
8+
const tag = defineHelper(
9+
'tabindex-mixin',
10+
'<slot></slot>',
11+
(Base) => class extends TabindexMixin(baseMixin(Base)) {},
12+
);
1413

15-
describe('tabindex-mixin', () => {
1614
let element;
1715

1816
describe('default', () => {
1917
beforeEach(() => {
20-
element = fixtureSync(`<tabindex-mixin-element></tabindex-mixin-element>`);
18+
element = fixtureSync(`<${tag}></${tag}>`);
2119
});
2220

2321
it('should not have tabindex attribute by default', () => {
@@ -84,11 +82,19 @@ describe('tabindex-mixin', () => {
8482

8583
describe('custom', () => {
8684
beforeEach(() => {
87-
element = fixtureSync(`<tabindex-mixin-element tabindex="1"></tabindex-mixin-element>`);
85+
element = fixtureSync(`<${tag} tabindex="1"></${tag}>`);
8886
});
8987

9088
it('should set tabindex property to the custom value', () => {
9189
expect(element.tabindex).to.equal(1);
9290
});
9391
});
92+
};
93+
94+
describe('TabindexMixin + Polymer', () => {
95+
runTests(definePolymer, ControllerMixin);
96+
});
97+
98+
describe('TabindexMixin + Lit', () => {
99+
runTests(defineLit, PolylitMixin);
94100
});

0 commit comments

Comments
 (0)