@vaadin/a11y-base 24.8.0-alpha9 → 25.0.0-alpha1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/a11y-base",
3
- "version": "24.8.0-alpha9",
3
+ "version": "25.0.0-alpha1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -31,15 +31,14 @@
31
31
  ],
32
32
  "dependencies": {
33
33
  "@open-wc/dedupe-mixin": "^1.3.0",
34
- "@polymer/polymer": "^3.0.0",
35
- "@vaadin/component-base": "24.8.0-alpha9",
34
+ "@vaadin/component-base": "25.0.0-alpha1",
36
35
  "lit": "^3.0.0"
37
36
  },
38
37
  "devDependencies": {
39
- "@vaadin/chai-plugins": "24.8.0-alpha9",
40
- "@vaadin/test-runner-commands": "24.8.0-alpha9",
38
+ "@vaadin/chai-plugins": "25.0.0-alpha1",
39
+ "@vaadin/test-runner-commands": "25.0.0-alpha1",
41
40
  "@vaadin/testing-helpers": "^1.1.0",
42
41
  "sinon": "^18.0.0"
43
42
  },
44
- "gitHead": "4de3809275ddfd733b0d13fd02af8faf73eb6770"
43
+ "gitHead": "b8c22a4a0c64156210d0daac96b43ae4e5526d49"
45
44
  }
@@ -3,7 +3,7 @@
3
3
  * Copyright (c) 2021 - 2025 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
6
+ import { dedupeMixin } from '@open-wc/dedupe-mixin';
7
7
  import { FocusMixin } from './focus-mixin.js';
8
8
  import { TabindexMixin } from './tabindex-mixin.js';
9
9
 
@@ -14,7 +14,7 @@ import { TabindexMixin } from './tabindex-mixin.js';
14
14
  * @mixes FocusMixin
15
15
  * @mixes TabindexMixin
16
16
  */
17
- export const DelegateFocusMixin = dedupingMixin(
17
+ export const DelegateFocusMixin = dedupeMixin(
18
18
  (superclass) =>
19
19
  class DelegateFocusMixinClass extends FocusMixin(TabindexMixin(superclass)) {
20
20
  static get properties() {
@@ -42,6 +42,7 @@ export const DelegateFocusMixin = dedupingMixin(
42
42
  type: Object,
43
43
  readOnly: true,
44
44
  observer: '_focusElementChanged',
45
+ sync: true,
45
46
  },
46
47
 
47
48
  /**
@@ -228,6 +229,11 @@ export const DelegateFocusMixin = dedupingMixin(
228
229
  }
229
230
  this.tabindex = undefined;
230
231
  }
232
+
233
+ // Lit does not remove attribute when setting property to undefined
234
+ if (tabindex === undefined && this.hasAttribute('tabindex')) {
235
+ this.removeAttribute('tabindex');
236
+ }
231
237
  }
232
238
  },
233
239
  );
@@ -3,14 +3,14 @@
3
3
  * Copyright (c) 2021 - 2025 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
6
+ import { dedupeMixin } from '@open-wc/dedupe-mixin';
7
7
 
8
8
  /**
9
9
  * A mixin to provide disabled property for field components.
10
10
  *
11
11
  * @polymerMixin
12
12
  */
13
- export const DisabledMixin = dedupingMixin(
13
+ export const DisabledMixin = dedupeMixin(
14
14
  (superclass) =>
15
15
  class DisabledMixinClass extends superclass {
16
16
  static get properties() {
@@ -3,7 +3,7 @@
3
3
  * Copyright (c) 2021 - 2025 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
6
+ import { dedupeMixin } from '@open-wc/dedupe-mixin';
7
7
  import { isKeyboardActive } from './focus-utils.js';
8
8
 
9
9
  /**
@@ -11,7 +11,7 @@ import { isKeyboardActive } from './focus-utils.js';
11
11
  *
12
12
  * @polymerMixin
13
13
  */
14
- export const FocusMixin = dedupingMixin(
14
+ export const FocusMixin = dedupeMixin(
15
15
  (superclass) =>
16
16
  class FocusMixinClass extends superclass {
17
17
  /**
@@ -30,6 +30,14 @@ export const KeyboardDirectionMixin = (superclass) =>
30
30
  return true;
31
31
  }
32
32
 
33
+ /**
34
+ * @return {boolean}
35
+ * @protected
36
+ */
37
+ get _tabNavigation() {
38
+ return false;
39
+ }
40
+
33
41
  /** @protected */
34
42
  focus() {
35
43
  const items = this._getItems();
@@ -67,7 +75,7 @@ export const KeyboardDirectionMixin = (superclass) =>
67
75
  return;
68
76
  }
69
77
 
70
- const { key } = event;
78
+ const { key, shiftKey } = event;
71
79
  const items = this._getItems() || [];
72
80
  const currentIdx = items.indexOf(this.focused);
73
81
 
@@ -77,10 +85,10 @@ export const KeyboardDirectionMixin = (superclass) =>
77
85
  const isRTL = !this._vertical && this.getAttribute('dir') === 'rtl';
78
86
  const dirIncrement = isRTL ? -1 : 1;
79
87
 
80
- if (this.__isPrevKey(key)) {
88
+ if (this.__isPrevKeyPressed(key, shiftKey)) {
81
89
  increment = -dirIncrement;
82
90
  idx = currentIdx - dirIncrement;
83
- } else if (this.__isNextKey(key)) {
91
+ } else if (this.__isNextKeyPressed(key, shiftKey)) {
84
92
  increment = dirIncrement;
85
93
  idx = currentIdx + dirIncrement;
86
94
  } else if (key === 'Home') {
@@ -93,6 +101,17 @@ export const KeyboardDirectionMixin = (superclass) =>
93
101
 
94
102
  idx = this._getAvailableIndex(items, idx, increment, (item) => !isElementHidden(item));
95
103
 
104
+ if (
105
+ this._tabNavigation &&
106
+ key === 'Tab' &&
107
+ ((idx > currentIdx && event.shiftKey) || (idx < currentIdx && !event.shiftKey))
108
+ ) {
109
+ // Prevent "roving tabindex" logic and let the normal Tab behavior if
110
+ // - currently on the first focusable item and Shift + Tab is pressed,
111
+ // - currently on the last focusable item and Tab is pressed.
112
+ return;
113
+ }
114
+
96
115
  if (idx >= 0) {
97
116
  event.preventDefault();
98
117
  this._focus(idx, true);
@@ -101,20 +120,30 @@ export const KeyboardDirectionMixin = (superclass) =>
101
120
 
102
121
  /**
103
122
  * @param {string} key
123
+ * @param {boolean} shiftKey
104
124
  * @return {boolean}
105
125
  * @private
106
126
  */
107
- __isPrevKey(key) {
108
- return this._vertical ? key === 'ArrowUp' : key === 'ArrowLeft';
127
+ __isPrevKeyPressed(key, shiftKey) {
128
+ if (this._vertical) {
129
+ return key === 'ArrowUp';
130
+ }
131
+
132
+ return key === 'ArrowLeft' || (this._tabNavigation && key === 'Tab' && shiftKey);
109
133
  }
110
134
 
111
135
  /**
112
136
  * @param {string} key
137
+ * @param {boolean} shiftKey
113
138
  * @return {boolean}
114
139
  * @private
115
140
  */
116
- __isNextKey(key) {
117
- return this._vertical ? key === 'ArrowDown' : key === 'ArrowRight';
141
+ __isNextKeyPressed(key, shiftKey) {
142
+ if (this._vertical) {
143
+ return key === 'ArrowDown';
144
+ }
145
+
146
+ return key === 'ArrowRight' || (this._tabNavigation && key === 'Tab' && !shiftKey);
118
147
  }
119
148
 
120
149
  /**
@@ -3,7 +3,7 @@
3
3
  * Copyright (c) 2021 - 2025 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
6
+ import { dedupeMixin } from '@open-wc/dedupe-mixin';
7
7
 
8
8
  /**
9
9
  * A mixin that manages keyboard handling.
@@ -12,7 +12,7 @@ import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
12
12
  *
13
13
  * @polymerMixin
14
14
  */
15
- export const KeyboardMixin = dedupingMixin(
15
+ export const KeyboardMixin = dedupeMixin(
16
16
  (superclass) =>
17
17
  class KeyboardMixinClass extends superclass {
18
18
  /** @protected */
@@ -27,6 +27,7 @@ export const TabindexMixin = (superclass) =>
27
27
  type: Number,
28
28
  reflectToAttribute: true,
29
29
  observer: '_tabindexChanged',
30
+ sync: true,
30
31
  },
31
32
 
32
33
  /**
@@ -60,9 +61,13 @@ export const TabindexMixin = (superclass) =>
60
61
  if (this.tabindex !== undefined) {
61
62
  this._lastTabIndex = this.tabindex;
62
63
  }
63
- this.tabindex = -1;
64
+ this.setAttribute('tabindex', '-1');
64
65
  } 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
+ }
66
71
  }
67
72
  }
68
73
 
@@ -80,7 +85,7 @@ export const TabindexMixin = (superclass) =>
80
85
 
81
86
  if (this.disabled && tabindex !== -1) {
82
87
  this._lastTabIndex = tabindex;
83
- this.tabindex = -1;
88
+ this.setAttribute('tabindex', '-1');
84
89
  }
85
90
  }
86
91