@vaadin/field-base 23.0.0-alpha1 → 23.0.0-alpha5
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/LICENSE +1 -1
- package/package.json +4 -3
- package/src/checked-mixin.d.ts +1 -1
- package/src/checked-mixin.js +1 -1
- package/src/delegate-focus-mixin.d.ts +1 -1
- package/src/delegate-focus-mixin.js +1 -1
- package/src/delegate-state-mixin.d.ts +1 -1
- package/src/delegate-state-mixin.js +1 -1
- package/src/field-aria-controller.d.ts +1 -1
- package/src/field-aria-controller.js +5 -8
- package/src/field-mixin.d.ts +3 -1
- package/src/field-mixin.js +49 -192
- package/src/helper-controller.d.ts +23 -0
- package/src/helper-controller.js +185 -0
- package/src/input-constraints-mixin.d.ts +1 -1
- package/src/input-constraints-mixin.js +2 -3
- package/src/input-control-mixin.d.ts +1 -1
- package/src/input-control-mixin.js +1 -1
- package/src/input-controller.d.ts +3 -3
- package/src/input-controller.js +5 -4
- package/src/input-field-mixin.d.ts +1 -1
- package/src/input-field-mixin.js +1 -1
- package/src/input-mixin.d.ts +1 -1
- package/src/input-mixin.js +1 -1
- package/src/label-controller.d.ts +26 -0
- package/src/label-controller.js +186 -0
- package/src/label-mixin.d.ts +4 -3
- package/src/label-mixin.js +10 -49
- package/src/labelled-input-controller.d.ts +1 -1
- package/src/labelled-input-controller.js +17 -4
- package/src/pattern-mixin.d.ts +1 -1
- package/src/pattern-mixin.js +1 -2
- package/src/shadow-focus-mixin.d.ts +1 -1
- package/src/shadow-focus-mixin.js +1 -1
- package/src/slot-label-mixin.d.ts +1 -1
- package/src/slot-label-mixin.js +1 -14
- package/src/slot-styles-mixin.d.ts +1 -1
- package/src/slot-styles-mixin.js +1 -1
- package/src/slot-target-mixin.d.ts +1 -1
- package/src/slot-target-mixin.js +1 -1
- package/src/styles/clear-button-styles.d.ts +1 -1
- package/src/styles/clear-button-styles.js +1 -1
- package/src/styles/field-shared-styles.d.ts +1 -1
- package/src/styles/field-shared-styles.js +1 -1
- package/src/styles/input-field-container-styles.d.ts +1 -1
- package/src/styles/input-field-container-styles.js +1 -1
- package/src/styles/input-field-shared-styles.d.ts +1 -1
- package/src/styles/input-field-shared-styles.js +1 -1
- package/src/text-area-controller.d.ts +3 -3
- package/src/text-area-controller.js +5 -4
- package/src/utils.d.ts +16 -0
- package/src/utils.js +56 -0
- package/src/validate-mixin.d.ts +1 -1
- package/src/validate-mixin.js +1 -1
- package/src/virtual-keyboard-controller.d.ts +14 -0
- package/src/virtual-keyboard-controller.js +38 -0
- package/src/slot-controller.d.ts +0 -8
- package/src/slot-controller.js +0 -36
package/LICENSE
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/field-base",
|
|
3
|
-
"version": "23.0.0-
|
|
3
|
+
"version": "23.0.0-alpha5",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"main": "index.js",
|
|
20
20
|
"module": "index.js",
|
|
21
|
+
"type": "module",
|
|
21
22
|
"files": [
|
|
22
23
|
"index.d.ts",
|
|
23
24
|
"index.js",
|
|
@@ -31,7 +32,7 @@
|
|
|
31
32
|
"dependencies": {
|
|
32
33
|
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
33
34
|
"@polymer/polymer": "^3.0.0",
|
|
34
|
-
"@vaadin/component-base": "23.0.0-
|
|
35
|
+
"@vaadin/component-base": "23.0.0-alpha5",
|
|
35
36
|
"lit": "^2.0.0"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
@@ -39,5 +40,5 @@
|
|
|
39
40
|
"@vaadin/testing-helpers": "^0.3.2",
|
|
40
41
|
"sinon": "^9.2.1"
|
|
41
42
|
},
|
|
42
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "74f9294964eb8552d96578c14af6ad214f5257bc"
|
|
43
44
|
}
|
package/src/checked-mixin.d.ts
CHANGED
package/src/checked-mixin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 Vaadin Ltd.
|
|
3
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 Vaadin Ltd.
|
|
3
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 Vaadin Ltd.
|
|
3
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 Vaadin Ltd.
|
|
3
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
+
import { addValueToAttribute, removeValueFromAttribute } from './utils.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* A controller for managing ARIA attributes for a field element:
|
|
@@ -160,16 +161,12 @@ export class FieldAriaController {
|
|
|
160
161
|
return;
|
|
161
162
|
}
|
|
162
163
|
|
|
163
|
-
const value = this.__target.getAttribute(attr);
|
|
164
|
-
const ids = value ? new Set(value.split(' ')) : new Set();
|
|
165
|
-
|
|
166
164
|
if (oldId) {
|
|
167
|
-
|
|
165
|
+
removeValueFromAttribute(this.__target, attr, oldId);
|
|
168
166
|
}
|
|
167
|
+
|
|
169
168
|
if (newId) {
|
|
170
|
-
|
|
169
|
+
addValueToAttribute(this.__target, attr, newId);
|
|
171
170
|
}
|
|
172
|
-
|
|
173
|
-
this.__target.setAttribute(attr, [...ids].join(' '));
|
|
174
171
|
}
|
|
175
172
|
}
|
package/src/field-mixin.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 Vaadin Ltd.
|
|
3
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import { Constructor } from '@open-wc/dedupe-mixin';
|
|
7
7
|
import { ControllerMixinClass } from '@vaadin/component-base/src/controller-mixin.js';
|
|
8
|
+
import { SlotMixinClass } from '@vaadin/component-base/src/slot-mixin.js';
|
|
8
9
|
import { LabelMixinClass } from './label-mixin.js';
|
|
9
10
|
import { ValidateMixinClass } from './validate-mixin.js';
|
|
10
11
|
|
|
@@ -17,6 +18,7 @@ export declare function FieldMixin<T extends Constructor<HTMLElement>>(
|
|
|
17
18
|
Constructor<ControllerMixinClass> &
|
|
18
19
|
Constructor<FieldMixinClass> &
|
|
19
20
|
Constructor<LabelMixinClass> &
|
|
21
|
+
Constructor<SlotMixinClass> &
|
|
20
22
|
Constructor<ValidateMixinClass>;
|
|
21
23
|
|
|
22
24
|
export declare class FieldMixinClass {
|
package/src/field-mixin.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 Vaadin Ltd.
|
|
3
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
-
import { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js';
|
|
7
|
-
import { animationFrame } from '@vaadin/component-base/src/async.js';
|
|
8
6
|
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
|
|
9
|
-
import {
|
|
7
|
+
import { SlotMixin } from '@vaadin/component-base/src/slot-mixin.js';
|
|
10
8
|
import { FieldAriaController } from './field-aria-controller.js';
|
|
9
|
+
import { HelperController } from './helper-controller.js';
|
|
11
10
|
import { LabelMixin } from './label-mixin.js';
|
|
12
11
|
import { ValidateMixin } from './validate-mixin.js';
|
|
13
12
|
|
|
@@ -17,10 +16,11 @@ import { ValidateMixin } from './validate-mixin.js';
|
|
|
17
16
|
* @polymerMixin
|
|
18
17
|
* @mixes ControllerMixin
|
|
19
18
|
* @mixes LabelMixin
|
|
19
|
+
* @mixes SlotMixin
|
|
20
20
|
* @mixes ValidateMixin
|
|
21
21
|
*/
|
|
22
22
|
export const FieldMixin = (superclass) =>
|
|
23
|
-
class FieldMixinClass extends ValidateMixin(LabelMixin(ControllerMixin(superclass))) {
|
|
23
|
+
class FieldMixinClass extends ValidateMixin(LabelMixin(ControllerMixin(SlotMixin(superclass)))) {
|
|
24
24
|
static get properties() {
|
|
25
25
|
return {
|
|
26
26
|
/**
|
|
@@ -68,13 +68,7 @@ export const FieldMixin = (superclass) =>
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
static get observers() {
|
|
71
|
-
return [
|
|
72
|
-
'__observeOffsetHeight(errorMessage, invalid, label, helperText)',
|
|
73
|
-
'_updateErrorMessage(invalid, errorMessage)',
|
|
74
|
-
'_invalidChanged(invalid)',
|
|
75
|
-
'_requiredChanged(required)',
|
|
76
|
-
'_helperIdChanged(_helperId)'
|
|
77
|
-
];
|
|
71
|
+
return ['_updateErrorMessage(invalid, errorMessage)', '_invalidChanged(invalid)', '_requiredChanged(required)'];
|
|
78
72
|
}
|
|
79
73
|
|
|
80
74
|
/**
|
|
@@ -85,12 +79,17 @@ export const FieldMixin = (superclass) =>
|
|
|
85
79
|
return this._getDirectSlotChild('error-message');
|
|
86
80
|
}
|
|
87
81
|
|
|
82
|
+
/** @protected */
|
|
83
|
+
get _helperId() {
|
|
84
|
+
return this._helperController.helperId;
|
|
85
|
+
}
|
|
86
|
+
|
|
88
87
|
/**
|
|
89
88
|
* @protected
|
|
90
89
|
* @return {HTMLElement}
|
|
91
90
|
*/
|
|
92
91
|
get _helperNode() {
|
|
93
|
-
return this.
|
|
92
|
+
return this._helperController.node;
|
|
94
93
|
}
|
|
95
94
|
|
|
96
95
|
constructor() {
|
|
@@ -99,12 +98,22 @@ export const FieldMixin = (superclass) =>
|
|
|
99
98
|
// Ensure every instance has unique ID
|
|
100
99
|
const uniqueId = (FieldMixinClass._uniqueFieldId = 1 + FieldMixinClass._uniqueFieldId || 0);
|
|
101
100
|
this._errorId = `error-${this.localName}-${uniqueId}`;
|
|
102
|
-
this._helperId = `helper-${this.localName}-${uniqueId}`;
|
|
103
|
-
|
|
104
|
-
// Save generated ID to restore later
|
|
105
|
-
this.__savedHelperId = this._helperId;
|
|
106
101
|
|
|
107
102
|
this._fieldAriaController = new FieldAriaController(this);
|
|
103
|
+
this._helperController = new HelperController(this);
|
|
104
|
+
|
|
105
|
+
this.addController(this._fieldAriaController);
|
|
106
|
+
this.addController(this._helperController);
|
|
107
|
+
|
|
108
|
+
this._labelController.addEventListener('label-changed', (event) => {
|
|
109
|
+
const { hasLabel, node } = event.detail;
|
|
110
|
+
this.__labelChanged(hasLabel, node);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
this._helperController.addEventListener('helper-changed', (event) => {
|
|
114
|
+
const { hasHelper, node } = event.detail;
|
|
115
|
+
this.__helperChanged(hasHelper, node);
|
|
116
|
+
});
|
|
108
117
|
}
|
|
109
118
|
|
|
110
119
|
/** @protected */
|
|
@@ -119,54 +128,6 @@ export const FieldMixin = (superclass) =>
|
|
|
119
128
|
|
|
120
129
|
this._updateErrorMessage(this.invalid, this.errorMessage);
|
|
121
130
|
}
|
|
122
|
-
|
|
123
|
-
const helper = this._helperNode;
|
|
124
|
-
if (helper) {
|
|
125
|
-
this.__applyCustomHelper(helper);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
this.__helperSlot = this.shadowRoot.querySelector('[name="helper"]');
|
|
129
|
-
|
|
130
|
-
this.__helperSlotObserver = new FlattenedNodesObserver(this.__helperSlot, (info) => {
|
|
131
|
-
const helper = this._currentHelper;
|
|
132
|
-
|
|
133
|
-
const newHelper = info.addedNodes.find((node) => node !== helper);
|
|
134
|
-
const oldHelper = info.removedNodes.find((node) => node === helper);
|
|
135
|
-
|
|
136
|
-
if (newHelper) {
|
|
137
|
-
// Custom helper is added, remove the previous one.
|
|
138
|
-
if (helper && helper.isConnected) {
|
|
139
|
-
this.removeChild(helper);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
this.__applyCustomHelper(newHelper);
|
|
143
|
-
|
|
144
|
-
this.__helperIdObserver = new MutationObserver((mutations) => {
|
|
145
|
-
mutations.forEach((mutation) => {
|
|
146
|
-
// only handle helper nodes
|
|
147
|
-
if (
|
|
148
|
-
mutation.type === 'attributes' &&
|
|
149
|
-
mutation.attributeName === 'id' &&
|
|
150
|
-
mutation.target === this._currentHelper &&
|
|
151
|
-
mutation.target.id !== this.__savedHelperId
|
|
152
|
-
) {
|
|
153
|
-
this.__updateHelperId(mutation.target);
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
this.__helperIdObserver.observe(newHelper, { attributes: true });
|
|
159
|
-
} else if (oldHelper) {
|
|
160
|
-
// The observer does not exist when default helper is removed.
|
|
161
|
-
if (this.__helperIdObserver) {
|
|
162
|
-
this.__helperIdObserver.disconnect();
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
this.__applyDefaultHelper(this.helperText);
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
this.addController(this._fieldAriaController);
|
|
170
131
|
}
|
|
171
132
|
|
|
172
133
|
/** @private */
|
|
@@ -178,107 +139,21 @@ export const FieldMixin = (superclass) =>
|
|
|
178
139
|
}
|
|
179
140
|
}
|
|
180
141
|
|
|
181
|
-
/**
|
|
182
|
-
* @param {HTMLElement} helper
|
|
183
|
-
* @private
|
|
184
|
-
*/
|
|
185
|
-
__applyCustomHelper(helper) {
|
|
186
|
-
this.__updateHelperId(helper);
|
|
187
|
-
this._currentHelper = helper;
|
|
188
|
-
this.__toggleHasHelper(helper.children.length > 0 || this.__isNotEmpty(helper.textContent));
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* @param {string} helperText
|
|
193
|
-
* @private
|
|
194
|
-
*/
|
|
195
|
-
__isNotEmpty(helperText) {
|
|
196
|
-
return helperText && helperText.trim() !== '';
|
|
197
|
-
}
|
|
198
|
-
|
|
199
142
|
/** @private */
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
helper.setAttribute('slot', 'helper');
|
|
206
|
-
this.__defaultHelper = helper;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
helper.id = this.__savedHelperId;
|
|
210
|
-
this._helperId = helper.id;
|
|
211
|
-
this.appendChild(helper);
|
|
212
|
-
this._currentHelper = helper;
|
|
213
|
-
|
|
214
|
-
return helper;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* @param {string} helperText
|
|
219
|
-
* @private
|
|
220
|
-
*/
|
|
221
|
-
__applyDefaultHelper(helperText) {
|
|
222
|
-
let helper = this._helperNode;
|
|
223
|
-
|
|
224
|
-
const hasHelperText = this.__isNotEmpty(helperText);
|
|
225
|
-
if (hasHelperText && !helper) {
|
|
226
|
-
// Create helper lazily
|
|
227
|
-
helper = this.__attachDefaultHelper();
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// Only set text content for default helper
|
|
231
|
-
if (helper && helper === this.__defaultHelper) {
|
|
232
|
-
helper.textContent = helperText;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
this.__toggleHasHelper(hasHelperText);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* @param {boolean} hasHelper
|
|
240
|
-
* @private
|
|
241
|
-
*/
|
|
242
|
-
__toggleHasHelper(hasHelper) {
|
|
243
|
-
this.toggleAttribute('has-helper', hasHelper);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Dispatch an event if a specific size measurement property has changed.
|
|
248
|
-
* Supporting multiple properties here is needed for `vaadin-text-area`.
|
|
249
|
-
* @protected
|
|
250
|
-
*/
|
|
251
|
-
_dispatchIronResizeEventIfNeeded(prop, value) {
|
|
252
|
-
const oldSize = '__old' + prop;
|
|
253
|
-
if (this[oldSize] !== undefined && this[oldSize] !== value) {
|
|
254
|
-
this.dispatchEvent(new CustomEvent('iron-resize', { bubbles: true, composed: true }));
|
|
143
|
+
__helperChanged(hasHelper, helperNode) {
|
|
144
|
+
if (hasHelper) {
|
|
145
|
+
this._fieldAriaController.setHelperId(helperNode.id);
|
|
146
|
+
} else {
|
|
147
|
+
this._fieldAriaController.setHelperId(null);
|
|
255
148
|
}
|
|
256
|
-
|
|
257
|
-
this[oldSize] = value;
|
|
258
149
|
}
|
|
259
150
|
|
|
260
151
|
/** @private */
|
|
261
|
-
|
|
262
|
-
this.__observeOffsetHeightDebouncer = Debouncer.debounce(
|
|
263
|
-
this.__observeOffsetHeightDebouncer,
|
|
264
|
-
animationFrame,
|
|
265
|
-
() => {
|
|
266
|
-
this._dispatchIronResizeEventIfNeeded('Height', this.offsetHeight);
|
|
267
|
-
}
|
|
268
|
-
);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* @protected
|
|
273
|
-
* @override
|
|
274
|
-
*/
|
|
275
|
-
_toggleHasLabelAttribute() {
|
|
276
|
-
super._toggleHasLabelAttribute();
|
|
277
|
-
|
|
152
|
+
__labelChanged(hasLabel, labelNode) {
|
|
278
153
|
// Label ID should be only added when the label content is present.
|
|
279
154
|
// Otherwise, it may conflict with an `aria-label` attribute possibly added by the user.
|
|
280
|
-
if (
|
|
281
|
-
this._fieldAriaController.setLabelId(
|
|
155
|
+
if (hasLabel) {
|
|
156
|
+
this._fieldAriaController.setLabelId(labelNode.id);
|
|
282
157
|
} else {
|
|
283
158
|
this._fieldAriaController.setLabelId(null);
|
|
284
159
|
}
|
|
@@ -301,6 +176,7 @@ export const FieldMixin = (superclass) =>
|
|
|
301
176
|
}
|
|
302
177
|
const hasError = Boolean(invalid && errorMessage);
|
|
303
178
|
error.textContent = hasError ? errorMessage : '';
|
|
179
|
+
error.hidden = !hasError;
|
|
304
180
|
this.toggleAttribute('has-error-message', hasError);
|
|
305
181
|
|
|
306
182
|
// Role alert will make the error message announce immediately
|
|
@@ -312,29 +188,12 @@ export const FieldMixin = (superclass) =>
|
|
|
312
188
|
}
|
|
313
189
|
}
|
|
314
190
|
|
|
315
|
-
/**
|
|
316
|
-
* @param {HTMLElement} customHelper
|
|
317
|
-
* @private
|
|
318
|
-
*/
|
|
319
|
-
__updateHelperId(customHelper) {
|
|
320
|
-
let newId;
|
|
321
|
-
|
|
322
|
-
if (customHelper.id) {
|
|
323
|
-
newId = customHelper.id;
|
|
324
|
-
} else {
|
|
325
|
-
newId = this.__savedHelperId;
|
|
326
|
-
customHelper.id = newId;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
this._helperId = newId;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
191
|
/**
|
|
333
192
|
* @param {string} helperText
|
|
334
193
|
* @protected
|
|
335
194
|
*/
|
|
336
195
|
_helperTextChanged(helperText) {
|
|
337
|
-
this.
|
|
196
|
+
this._helperController.setHelperText(helperText);
|
|
338
197
|
}
|
|
339
198
|
|
|
340
199
|
/**
|
|
@@ -355,25 +214,23 @@ export const FieldMixin = (superclass) =>
|
|
|
355
214
|
this._fieldAriaController.setRequired(required);
|
|
356
215
|
}
|
|
357
216
|
|
|
358
|
-
/**
|
|
359
|
-
* @param {string} helperId
|
|
360
|
-
* @protected
|
|
361
|
-
*/
|
|
362
|
-
_helperIdChanged(helperId) {
|
|
363
|
-
this._fieldAriaController.setHelperId(helperId);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
217
|
/**
|
|
367
218
|
* @param {boolean} required
|
|
368
219
|
* @protected
|
|
369
220
|
*/
|
|
370
221
|
_invalidChanged(invalid) {
|
|
371
|
-
//
|
|
372
|
-
//
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
222
|
+
// This timeout is needed to prevent NVDA from announcing the error message twice:
|
|
223
|
+
// 1. Once adding the `[role=alert]` attribute by the `_updateErrorMessage` method (OK).
|
|
224
|
+
// 2. Once linking the error ID with the ARIA target here (unwanted).
|
|
225
|
+
// Related issue: https://github.com/vaadin/web-components/issues/3061.
|
|
226
|
+
setTimeout(() => {
|
|
227
|
+
// Error message ID needs to be dynamically added / removed based on the validity
|
|
228
|
+
// Otherwise assistive technologies would announce the error, even if we hide it.
|
|
229
|
+
if (invalid) {
|
|
230
|
+
this._fieldAriaController.setErrorId(this._errorId);
|
|
231
|
+
} else {
|
|
232
|
+
this._fieldAriaController.setErrorId(null);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
378
235
|
}
|
|
379
236
|
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A controller that manages the helper node content.
|
|
10
|
+
*/
|
|
11
|
+
export class HelperController extends SlotController {
|
|
12
|
+
/**
|
|
13
|
+
* String used for the helper text.
|
|
14
|
+
*/
|
|
15
|
+
helperText: string | null | undefined;
|
|
16
|
+
|
|
17
|
+
helperId: string;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Set helper text based on corresponding host property.
|
|
21
|
+
*/
|
|
22
|
+
setHelperText(helperText: string): void;
|
|
23
|
+
}
|