@vaadin/field-base 25.3.0-alpha1 → 25.3.0-alpha11
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/custom-elements.json +88 -18
- package/package.json +7 -7
- package/src/clear-button-mixin.d.ts +1 -4
- package/src/clear-button-mixin.js +1 -4
- package/src/field-mixin.d.ts +15 -10
- package/src/field-mixin.js +92 -80
- package/src/labelled-input-controller.js +6 -9
- package/src/styles/checkable-base-styles.js +40 -7
- package/src/virtual-keyboard-controller.js +4 -5
package/custom-elements.json
CHANGED
|
@@ -150,7 +150,7 @@
|
|
|
150
150
|
"type": {
|
|
151
151
|
"text": "boolean"
|
|
152
152
|
},
|
|
153
|
-
"description": "Set to true to display the clear icon which clears the input.\
|
|
153
|
+
"description": "Set to true to display the clear icon which clears the input.\nThis also enables clearing the input when pressing Esc key.",
|
|
154
154
|
"attribute": "clear-button-visible"
|
|
155
155
|
},
|
|
156
156
|
{
|
|
@@ -174,7 +174,7 @@
|
|
|
174
174
|
"type": {
|
|
175
175
|
"text": "boolean"
|
|
176
176
|
},
|
|
177
|
-
"description": "Set to true to display the clear icon which clears the input.\
|
|
177
|
+
"description": "Set to true to display the clear icon which clears the input.\nThis also enables clearing the input when pressing Esc key.",
|
|
178
178
|
"fieldName": "clearButtonVisible"
|
|
179
179
|
},
|
|
180
180
|
{
|
|
@@ -227,6 +227,16 @@
|
|
|
227
227
|
"description": "A mixin to provide common field logic: label, error message and helper text.",
|
|
228
228
|
"name": "FieldMixin",
|
|
229
229
|
"members": [
|
|
230
|
+
{
|
|
231
|
+
"kind": "field",
|
|
232
|
+
"name": "accessibleDescriptionRef",
|
|
233
|
+
"privacy": "public",
|
|
234
|
+
"type": {
|
|
235
|
+
"text": "string"
|
|
236
|
+
},
|
|
237
|
+
"description": "A space-separated list of IDs referencing the elements that\ndescribe the component for screen reader users. The referenced\nelements are announced in addition to the helper text and\nthe error message.",
|
|
238
|
+
"attribute": "accessible-description-ref"
|
|
239
|
+
},
|
|
230
240
|
{
|
|
231
241
|
"kind": "field",
|
|
232
242
|
"name": "accessibleName",
|
|
@@ -234,7 +244,7 @@
|
|
|
234
244
|
"type": {
|
|
235
245
|
"text": "string"
|
|
236
246
|
},
|
|
237
|
-
"description": "String used to label the component
|
|
247
|
+
"description": "String used to label the component for screen reader users.",
|
|
238
248
|
"attribute": "accessible-name"
|
|
239
249
|
},
|
|
240
250
|
{
|
|
@@ -244,7 +254,7 @@
|
|
|
244
254
|
"type": {
|
|
245
255
|
"text": "string"
|
|
246
256
|
},
|
|
247
|
-
"description": "
|
|
257
|
+
"description": "A space-separated list of IDs referencing the elements that\nlabel the component for screen reader users.",
|
|
248
258
|
"attribute": "accessible-name-ref"
|
|
249
259
|
},
|
|
250
260
|
{
|
|
@@ -353,12 +363,20 @@
|
|
|
353
363
|
}
|
|
354
364
|
],
|
|
355
365
|
"attributes": [
|
|
366
|
+
{
|
|
367
|
+
"name": "accessible-description-ref",
|
|
368
|
+
"type": {
|
|
369
|
+
"text": "string"
|
|
370
|
+
},
|
|
371
|
+
"description": "A space-separated list of IDs referencing the elements that\ndescribe the component for screen reader users. The referenced\nelements are announced in addition to the helper text and\nthe error message.",
|
|
372
|
+
"fieldName": "accessibleDescriptionRef"
|
|
373
|
+
},
|
|
356
374
|
{
|
|
357
375
|
"name": "accessible-name",
|
|
358
376
|
"type": {
|
|
359
377
|
"text": "string"
|
|
360
378
|
},
|
|
361
|
-
"description": "String used to label the component
|
|
379
|
+
"description": "String used to label the component for screen reader users.",
|
|
362
380
|
"fieldName": "accessibleName"
|
|
363
381
|
},
|
|
364
382
|
{
|
|
@@ -366,7 +384,7 @@
|
|
|
366
384
|
"type": {
|
|
367
385
|
"text": "string"
|
|
368
386
|
},
|
|
369
|
-
"description": "
|
|
387
|
+
"description": "A space-separated list of IDs referencing the elements that\nlabel the component for screen reader users.",
|
|
370
388
|
"fieldName": "accessibleNameRef"
|
|
371
389
|
},
|
|
372
390
|
{
|
|
@@ -690,6 +708,20 @@
|
|
|
690
708
|
"description": "A mixin to provide shared logic for the editable form input controls.",
|
|
691
709
|
"name": "InputControlMixin",
|
|
692
710
|
"members": [
|
|
711
|
+
{
|
|
712
|
+
"kind": "field",
|
|
713
|
+
"name": "accessibleDescriptionRef",
|
|
714
|
+
"privacy": "public",
|
|
715
|
+
"type": {
|
|
716
|
+
"text": "string"
|
|
717
|
+
},
|
|
718
|
+
"description": "A space-separated list of IDs referencing the elements that\ndescribe the component for screen reader users. The referenced\nelements are announced in addition to the helper text and\nthe error message.",
|
|
719
|
+
"attribute": "accessible-description-ref",
|
|
720
|
+
"inheritedFrom": {
|
|
721
|
+
"name": "FieldMixin",
|
|
722
|
+
"module": "src/field-mixin.js"
|
|
723
|
+
}
|
|
724
|
+
},
|
|
693
725
|
{
|
|
694
726
|
"kind": "field",
|
|
695
727
|
"name": "accessibleName",
|
|
@@ -697,7 +729,7 @@
|
|
|
697
729
|
"type": {
|
|
698
730
|
"text": "string"
|
|
699
731
|
},
|
|
700
|
-
"description": "String used to label the component
|
|
732
|
+
"description": "String used to label the component for screen reader users.",
|
|
701
733
|
"attribute": "accessible-name",
|
|
702
734
|
"inheritedFrom": {
|
|
703
735
|
"name": "FieldMixin",
|
|
@@ -711,7 +743,7 @@
|
|
|
711
743
|
"type": {
|
|
712
744
|
"text": "string"
|
|
713
745
|
},
|
|
714
|
-
"description": "
|
|
746
|
+
"description": "A space-separated list of IDs referencing the elements that\nlabel the component for screen reader users.",
|
|
715
747
|
"attribute": "accessible-name-ref",
|
|
716
748
|
"inheritedFrom": {
|
|
717
749
|
"name": "FieldMixin",
|
|
@@ -782,7 +814,7 @@
|
|
|
782
814
|
"type": {
|
|
783
815
|
"text": "boolean"
|
|
784
816
|
},
|
|
785
|
-
"description": "Set to true to display the clear icon which clears the input.\
|
|
817
|
+
"description": "Set to true to display the clear icon which clears the input.\nThis also enables clearing the input when pressing Esc key.",
|
|
786
818
|
"attribute": "clear-button-visible",
|
|
787
819
|
"inheritedFrom": {
|
|
788
820
|
"name": "ClearButtonMixin",
|
|
@@ -957,12 +989,24 @@
|
|
|
957
989
|
}
|
|
958
990
|
],
|
|
959
991
|
"attributes": [
|
|
992
|
+
{
|
|
993
|
+
"name": "accessible-description-ref",
|
|
994
|
+
"type": {
|
|
995
|
+
"text": "string"
|
|
996
|
+
},
|
|
997
|
+
"description": "A space-separated list of IDs referencing the elements that\ndescribe the component for screen reader users. The referenced\nelements are announced in addition to the helper text and\nthe error message.",
|
|
998
|
+
"fieldName": "accessibleDescriptionRef",
|
|
999
|
+
"inheritedFrom": {
|
|
1000
|
+
"name": "FieldMixin",
|
|
1001
|
+
"module": "src/field-mixin.js"
|
|
1002
|
+
}
|
|
1003
|
+
},
|
|
960
1004
|
{
|
|
961
1005
|
"name": "accessible-name",
|
|
962
1006
|
"type": {
|
|
963
1007
|
"text": "string"
|
|
964
1008
|
},
|
|
965
|
-
"description": "String used to label the component
|
|
1009
|
+
"description": "String used to label the component for screen reader users.",
|
|
966
1010
|
"fieldName": "accessibleName",
|
|
967
1011
|
"inheritedFrom": {
|
|
968
1012
|
"name": "FieldMixin",
|
|
@@ -974,7 +1018,7 @@
|
|
|
974
1018
|
"type": {
|
|
975
1019
|
"text": "string"
|
|
976
1020
|
},
|
|
977
|
-
"description": "
|
|
1021
|
+
"description": "A space-separated list of IDs referencing the elements that\nlabel the component for screen reader users.",
|
|
978
1022
|
"fieldName": "accessibleNameRef",
|
|
979
1023
|
"inheritedFrom": {
|
|
980
1024
|
"name": "FieldMixin",
|
|
@@ -1014,7 +1058,7 @@
|
|
|
1014
1058
|
"type": {
|
|
1015
1059
|
"text": "boolean"
|
|
1016
1060
|
},
|
|
1017
|
-
"description": "Set to true to display the clear icon which clears the input.\
|
|
1061
|
+
"description": "Set to true to display the clear icon which clears the input.\nThis also enables clearing the input when pressing Esc key.",
|
|
1018
1062
|
"fieldName": "clearButtonVisible",
|
|
1019
1063
|
"inheritedFrom": {
|
|
1020
1064
|
"name": "ClearButtonMixin",
|
|
@@ -1225,6 +1269,20 @@
|
|
|
1225
1269
|
"description": "A mixin to provide logic for vaadin-text-field and related components.",
|
|
1226
1270
|
"name": "InputFieldMixin",
|
|
1227
1271
|
"members": [
|
|
1272
|
+
{
|
|
1273
|
+
"kind": "field",
|
|
1274
|
+
"name": "accessibleDescriptionRef",
|
|
1275
|
+
"privacy": "public",
|
|
1276
|
+
"type": {
|
|
1277
|
+
"text": "string"
|
|
1278
|
+
},
|
|
1279
|
+
"description": "A space-separated list of IDs referencing the elements that\ndescribe the component for screen reader users. The referenced\nelements are announced in addition to the helper text and\nthe error message.",
|
|
1280
|
+
"attribute": "accessible-description-ref",
|
|
1281
|
+
"inheritedFrom": {
|
|
1282
|
+
"name": "FieldMixin",
|
|
1283
|
+
"module": "src/field-mixin.js"
|
|
1284
|
+
}
|
|
1285
|
+
},
|
|
1228
1286
|
{
|
|
1229
1287
|
"kind": "field",
|
|
1230
1288
|
"name": "accessibleName",
|
|
@@ -1232,7 +1290,7 @@
|
|
|
1232
1290
|
"type": {
|
|
1233
1291
|
"text": "string"
|
|
1234
1292
|
},
|
|
1235
|
-
"description": "String used to label the component
|
|
1293
|
+
"description": "String used to label the component for screen reader users.",
|
|
1236
1294
|
"attribute": "accessible-name",
|
|
1237
1295
|
"inheritedFrom": {
|
|
1238
1296
|
"name": "FieldMixin",
|
|
@@ -1246,7 +1304,7 @@
|
|
|
1246
1304
|
"type": {
|
|
1247
1305
|
"text": "string"
|
|
1248
1306
|
},
|
|
1249
|
-
"description": "
|
|
1307
|
+
"description": "A space-separated list of IDs referencing the elements that\nlabel the component for screen reader users.",
|
|
1250
1308
|
"attribute": "accessible-name-ref",
|
|
1251
1309
|
"inheritedFrom": {
|
|
1252
1310
|
"name": "FieldMixin",
|
|
@@ -1355,7 +1413,7 @@
|
|
|
1355
1413
|
"type": {
|
|
1356
1414
|
"text": "boolean"
|
|
1357
1415
|
},
|
|
1358
|
-
"description": "Set to true to display the clear icon which clears the input.\
|
|
1416
|
+
"description": "Set to true to display the clear icon which clears the input.\nThis also enables clearing the input when pressing Esc key.",
|
|
1359
1417
|
"attribute": "clear-button-visible",
|
|
1360
1418
|
"inheritedFrom": {
|
|
1361
1419
|
"name": "ClearButtonMixin",
|
|
@@ -1546,12 +1604,24 @@
|
|
|
1546
1604
|
}
|
|
1547
1605
|
],
|
|
1548
1606
|
"attributes": [
|
|
1607
|
+
{
|
|
1608
|
+
"name": "accessible-description-ref",
|
|
1609
|
+
"type": {
|
|
1610
|
+
"text": "string"
|
|
1611
|
+
},
|
|
1612
|
+
"description": "A space-separated list of IDs referencing the elements that\ndescribe the component for screen reader users. The referenced\nelements are announced in addition to the helper text and\nthe error message.",
|
|
1613
|
+
"fieldName": "accessibleDescriptionRef",
|
|
1614
|
+
"inheritedFrom": {
|
|
1615
|
+
"name": "FieldMixin",
|
|
1616
|
+
"module": "src/field-mixin.js"
|
|
1617
|
+
}
|
|
1618
|
+
},
|
|
1549
1619
|
{
|
|
1550
1620
|
"name": "accessible-name",
|
|
1551
1621
|
"type": {
|
|
1552
1622
|
"text": "string"
|
|
1553
1623
|
},
|
|
1554
|
-
"description": "String used to label the component
|
|
1624
|
+
"description": "String used to label the component for screen reader users.",
|
|
1555
1625
|
"fieldName": "accessibleName",
|
|
1556
1626
|
"inheritedFrom": {
|
|
1557
1627
|
"name": "FieldMixin",
|
|
@@ -1563,7 +1633,7 @@
|
|
|
1563
1633
|
"type": {
|
|
1564
1634
|
"text": "string"
|
|
1565
1635
|
},
|
|
1566
|
-
"description": "
|
|
1636
|
+
"description": "A space-separated list of IDs referencing the elements that\nlabel the component for screen reader users.",
|
|
1567
1637
|
"fieldName": "accessibleNameRef",
|
|
1568
1638
|
"inheritedFrom": {
|
|
1569
1639
|
"name": "FieldMixin",
|
|
@@ -1635,7 +1705,7 @@
|
|
|
1635
1705
|
"type": {
|
|
1636
1706
|
"text": "boolean"
|
|
1637
1707
|
},
|
|
1638
|
-
"description": "Set to true to display the clear icon which clears the input.\
|
|
1708
|
+
"description": "Set to true to display the clear icon which clears the input.\nThis also enables clearing the input when pressing Esc key.",
|
|
1639
1709
|
"fieldName": "clearButtonVisible",
|
|
1640
1710
|
"inheritedFrom": {
|
|
1641
1711
|
"name": "ClearButtonMixin",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/field-base",
|
|
3
|
-
"version": "25.3.0-
|
|
3
|
+
"version": "25.3.0-alpha11",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -32,17 +32,17 @@
|
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
35
|
-
"@vaadin/a11y-base": "25.3.0-
|
|
36
|
-
"@vaadin/component-base": "25.3.0-
|
|
35
|
+
"@vaadin/a11y-base": "25.3.0-alpha11",
|
|
36
|
+
"@vaadin/component-base": "25.3.0-alpha11",
|
|
37
37
|
"lit": "^3.0.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@vaadin/chai-plugins": "25.3.0-
|
|
41
|
-
"@vaadin/input-container": "25.3.0-
|
|
42
|
-
"@vaadin/test-runner-commands": "25.3.0-
|
|
40
|
+
"@vaadin/chai-plugins": "25.3.0-alpha11",
|
|
41
|
+
"@vaadin/input-container": "25.3.0-alpha11",
|
|
42
|
+
"@vaadin/test-runner-commands": "25.3.0-alpha11",
|
|
43
43
|
"@vaadin/testing-helpers": "^2.0.0",
|
|
44
44
|
"sinon": "^22.0.0"
|
|
45
45
|
},
|
|
46
46
|
"customElements": "custom-elements.json",
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "7e0c61a37e68d8971def9cdf28ad0548a0f530a9"
|
|
48
48
|
}
|
|
@@ -17,10 +17,7 @@ export declare function ClearButtonMixin<T extends Constructor<HTMLElement>>(
|
|
|
17
17
|
export declare class ClearButtonMixinClass {
|
|
18
18
|
/**
|
|
19
19
|
* Set to true to display the clear icon which clears the input.
|
|
20
|
-
*
|
|
21
|
-
* It is up to the component to choose where to place the clear icon:
|
|
22
|
-
* in the Shadow DOM or in the light DOM. In any way, a reference to
|
|
23
|
-
* the clear icon element should be provided via the `clearElement` getter.
|
|
20
|
+
* This also enables clearing the input when pressing Esc key.
|
|
24
21
|
*
|
|
25
22
|
* @attr {boolean} clear-button-visible
|
|
26
23
|
*/
|
|
@@ -17,10 +17,7 @@ export const ClearButtonMixin = (superclass) =>
|
|
|
17
17
|
return {
|
|
18
18
|
/**
|
|
19
19
|
* Set to true to display the clear icon which clears the input.
|
|
20
|
-
*
|
|
21
|
-
* It is up to the component to choose where to place the clear icon:
|
|
22
|
-
* in the Shadow DOM or in the light DOM. In any way, a reference to
|
|
23
|
-
* the clear icon element should be provided via the `clearElement` getter.
|
|
20
|
+
* This also enables clearing the input when pressing Esc key.
|
|
24
21
|
*
|
|
25
22
|
* @attr {boolean} clear-button-visible
|
|
26
23
|
*/
|
package/src/field-mixin.d.ts
CHANGED
|
@@ -30,17 +30,30 @@ export declare class FieldMixinClass {
|
|
|
30
30
|
errorMessage: string | null | undefined;
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
|
-
* String used to label the component
|
|
33
|
+
* String used to label the component for screen reader users.
|
|
34
|
+
*
|
|
34
35
|
* @attr {string} accessible-name
|
|
35
36
|
*/
|
|
36
37
|
accessibleName: string | null | undefined;
|
|
37
38
|
|
|
38
39
|
/**
|
|
39
|
-
*
|
|
40
|
+
* A space-separated list of IDs referencing the elements that
|
|
41
|
+
* label the component for screen reader users.
|
|
42
|
+
*
|
|
40
43
|
* @attr {string} accessible-name-ref
|
|
41
44
|
*/
|
|
42
45
|
accessibleNameRef: string | null | undefined;
|
|
43
46
|
|
|
47
|
+
/**
|
|
48
|
+
* A space-separated list of IDs referencing the elements that
|
|
49
|
+
* describe the component for screen reader users. The referenced
|
|
50
|
+
* elements are announced in addition to the helper text and
|
|
51
|
+
* the error message.
|
|
52
|
+
*
|
|
53
|
+
* @attr {string} accessible-description-ref
|
|
54
|
+
*/
|
|
55
|
+
accessibleDescriptionRef: string | null | undefined;
|
|
56
|
+
|
|
44
57
|
/**
|
|
45
58
|
* A target element to which ARIA attributes are set.
|
|
46
59
|
*/
|
|
@@ -49,12 +62,4 @@ export declare class FieldMixinClass {
|
|
|
49
62
|
protected readonly _errorNode: HTMLElement;
|
|
50
63
|
|
|
51
64
|
protected readonly _helperNode?: HTMLElement;
|
|
52
|
-
|
|
53
|
-
protected _helperTextChanged(helperText: string | null | undefined): void;
|
|
54
|
-
|
|
55
|
-
protected _ariaTargetChanged(target: HTMLElement): void;
|
|
56
|
-
|
|
57
|
-
protected _requiredChanged(required: boolean): void;
|
|
58
|
-
|
|
59
|
-
protected _invalidChanged(invalid: boolean): void;
|
|
60
65
|
}
|
package/src/field-mixin.js
CHANGED
|
@@ -22,7 +22,6 @@ export const FieldMixin = (superclass) =>
|
|
|
22
22
|
*/
|
|
23
23
|
ariaTarget: {
|
|
24
24
|
type: Object,
|
|
25
|
-
observer: '_ariaTargetChanged',
|
|
26
25
|
},
|
|
27
26
|
|
|
28
27
|
/**
|
|
@@ -32,7 +31,6 @@ export const FieldMixin = (superclass) =>
|
|
|
32
31
|
*/
|
|
33
32
|
errorMessage: {
|
|
34
33
|
type: String,
|
|
35
|
-
observer: '_errorMessageChanged',
|
|
36
34
|
},
|
|
37
35
|
|
|
38
36
|
/**
|
|
@@ -41,54 +39,59 @@ export const FieldMixin = (superclass) =>
|
|
|
41
39
|
*/
|
|
42
40
|
helperText: {
|
|
43
41
|
type: String,
|
|
44
|
-
observer: '_helperTextChanged',
|
|
45
42
|
},
|
|
46
43
|
|
|
47
44
|
/**
|
|
48
|
-
* String used to label the component
|
|
45
|
+
* String used to label the component for screen reader users.
|
|
46
|
+
*
|
|
49
47
|
* @attr {string} accessible-name
|
|
50
48
|
*/
|
|
51
49
|
accessibleName: {
|
|
52
50
|
type: String,
|
|
53
|
-
observer: '_accessibleNameChanged',
|
|
54
51
|
},
|
|
55
52
|
|
|
56
53
|
/**
|
|
57
|
-
*
|
|
54
|
+
* A space-separated list of IDs referencing the elements that
|
|
55
|
+
* label the component for screen reader users.
|
|
56
|
+
*
|
|
58
57
|
* @attr {string} accessible-name-ref
|
|
59
58
|
*/
|
|
60
59
|
accessibleNameRef: {
|
|
61
60
|
type: String,
|
|
62
|
-
observer: '_accessibleNameRefChanged',
|
|
63
61
|
},
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
62
|
|
|
67
|
-
|
|
68
|
-
|
|
63
|
+
/**
|
|
64
|
+
* A space-separated list of IDs referencing the elements that
|
|
65
|
+
* describe the component for screen reader users. The referenced
|
|
66
|
+
* elements are announced in addition to the helper text and
|
|
67
|
+
* the error message.
|
|
68
|
+
*
|
|
69
|
+
* @attr {string} accessible-description-ref
|
|
70
|
+
*/
|
|
71
|
+
accessibleDescriptionRef: {
|
|
72
|
+
type: String,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
constructor() {
|
|
72
78
|
super();
|
|
73
79
|
|
|
74
|
-
this._fieldAriaController = new FieldAriaController(this);
|
|
75
|
-
this._helperController = new HelperController(this);
|
|
76
|
-
this._errorController = new ErrorController(this);
|
|
77
|
-
|
|
78
|
-
this._errorController.addEventListener('slot-content-changed', (event) => {
|
|
79
|
-
this.toggleAttribute('has-error-message', event.detail.hasContent);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
80
|
this._labelController.addEventListener('slot-content-changed', (event) => {
|
|
83
|
-
|
|
84
|
-
this.__labelChanged(hasContent, node);
|
|
81
|
+
this.#onLabelSlotContentChange(event);
|
|
85
82
|
});
|
|
86
83
|
|
|
84
|
+
this._helperController = new HelperController(this);
|
|
87
85
|
this._helperController.addEventListener('slot-content-changed', (event) => {
|
|
88
|
-
|
|
89
|
-
this.toggleAttribute('has-helper', hasContent);
|
|
90
|
-
this.__helperChanged(hasContent, node);
|
|
86
|
+
this.#onHelperSlotContentChange(event);
|
|
91
87
|
});
|
|
88
|
+
|
|
89
|
+
this._errorController = new ErrorController(this);
|
|
90
|
+
this._errorController.addEventListener('slot-content-changed', (event) => {
|
|
91
|
+
this.#onErrorSlotContentChange(event);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
this._fieldAriaController = new FieldAriaController(this);
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
/**
|
|
@@ -116,76 +119,86 @@ export const FieldMixin = (superclass) =>
|
|
|
116
119
|
this.addController(this._errorController);
|
|
117
120
|
}
|
|
118
121
|
|
|
119
|
-
/** @
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
this.
|
|
122
|
+
/** @protected */
|
|
123
|
+
updated(props) {
|
|
124
|
+
super.updated(props);
|
|
125
|
+
|
|
126
|
+
if (props.has('invalid')) {
|
|
127
|
+
this._errorController.setInvalid(this.invalid);
|
|
125
128
|
}
|
|
126
|
-
}
|
|
127
129
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
if (props.has('errorMessage')) {
|
|
131
|
+
this._errorController.setErrorMessage(this.errorMessage);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (props.has('helperText')) {
|
|
135
|
+
this._helperController.setHelperText(this.helperText);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (props.has('ariaTarget')) {
|
|
139
|
+
this._fieldAriaController.setTarget(this.ariaTarget);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (props.has('required')) {
|
|
143
|
+
this._fieldAriaController.setRequired(this.required);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (props.has('accessibleName')) {
|
|
147
|
+
this.__updateFieldAriaControllerLabel();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (props.has('accessibleName') || props.has('accessibleNameRef')) {
|
|
151
|
+
this.__updateFieldAriaControllerLabelledBy();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (props.has('accessibleDescriptionRef')) {
|
|
155
|
+
this.__updateFieldAriaControllerDescribedBy();
|
|
156
|
+
}
|
|
131
157
|
}
|
|
132
158
|
|
|
133
|
-
/** @
|
|
134
|
-
|
|
135
|
-
this._fieldAriaController.
|
|
159
|
+
/** @private */
|
|
160
|
+
__updateFieldAriaControllerLabel() {
|
|
161
|
+
this._fieldAriaController.setLabel(this.accessibleName);
|
|
136
162
|
}
|
|
137
163
|
|
|
138
164
|
/** @private */
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if (
|
|
143
|
-
this.
|
|
144
|
-
} else {
|
|
145
|
-
|
|
165
|
+
__updateFieldAriaControllerLabelledBy() {
|
|
166
|
+
let id = null;
|
|
167
|
+
|
|
168
|
+
if (this.accessibleNameRef) {
|
|
169
|
+
id = this.accessibleNameRef;
|
|
170
|
+
} else if (this.hasAttribute('has-label') && !this.accessibleName) {
|
|
171
|
+
// Label ID should be only added when the label content is present
|
|
172
|
+
// and not overridden by `accessible-name` which sets `aria-label`.
|
|
173
|
+
id = this._labelNode?.id;
|
|
146
174
|
}
|
|
147
|
-
}
|
|
148
175
|
|
|
149
|
-
|
|
150
|
-
* @param {string | null | undefined} errorMessage
|
|
151
|
-
* @protected
|
|
152
|
-
*/
|
|
153
|
-
_errorMessageChanged(errorMessage) {
|
|
154
|
-
this._errorController.setErrorMessage(errorMessage);
|
|
176
|
+
this._fieldAriaController.setLabelledBy(id);
|
|
155
177
|
}
|
|
156
178
|
|
|
157
|
-
/**
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
*/
|
|
161
|
-
_helperTextChanged(helperText) {
|
|
162
|
-
this._helperController.setHelperText(helperText);
|
|
179
|
+
/** @private */
|
|
180
|
+
__updateFieldAriaControllerDescribedBy() {
|
|
181
|
+
this._fieldAriaController.setDescribedBy(this.accessibleDescriptionRef);
|
|
163
182
|
}
|
|
164
183
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
* @protected
|
|
168
|
-
*/
|
|
169
|
-
_ariaTargetChanged(target) {
|
|
170
|
-
if (target) {
|
|
171
|
-
this._fieldAriaController.setTarget(target);
|
|
172
|
-
}
|
|
184
|
+
#onLabelSlotContentChange(_event) {
|
|
185
|
+
this.__updateFieldAriaControllerLabelledBy();
|
|
173
186
|
}
|
|
174
187
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
188
|
+
#onHelperSlotContentChange(event) {
|
|
189
|
+
const { hasContent } = event.detail;
|
|
190
|
+
|
|
191
|
+
this.toggleAttribute('has-helper', hasContent);
|
|
192
|
+
|
|
193
|
+
if (hasContent) {
|
|
194
|
+
this._fieldAriaController.setHelperId(this._helperNode?.id);
|
|
195
|
+
} else {
|
|
196
|
+
this._fieldAriaController.setHelperId(null);
|
|
197
|
+
}
|
|
181
198
|
}
|
|
182
199
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
* @protected
|
|
186
|
-
*/
|
|
187
|
-
_invalidChanged(invalid) {
|
|
188
|
-
this._errorController.setInvalid(invalid);
|
|
200
|
+
#onErrorSlotContentChange(event) {
|
|
201
|
+
this.toggleAttribute('has-error-message', event.detail.hasContent);
|
|
189
202
|
|
|
190
203
|
// This timeout is needed to prevent NVDA from announcing the error message twice:
|
|
191
204
|
// 1. Once adding the `[role=alert]` attribute when updating `has-error-message` (OK).
|
|
@@ -194,9 +207,8 @@ export const FieldMixin = (superclass) =>
|
|
|
194
207
|
setTimeout(() => {
|
|
195
208
|
// Error message ID needs to be dynamically added / removed based on the validity
|
|
196
209
|
// Otherwise assistive technologies would announce the error, even if we hide it.
|
|
197
|
-
if (invalid) {
|
|
198
|
-
|
|
199
|
-
this._fieldAriaController.setErrorId(node?.id);
|
|
210
|
+
if (this.invalid) {
|
|
211
|
+
this._fieldAriaController.setErrorId(this._errorNode?.id);
|
|
200
212
|
} else {
|
|
201
213
|
this._fieldAriaController.setErrorId(null);
|
|
202
214
|
}
|
|
@@ -10,23 +10,21 @@
|
|
|
10
10
|
export class LabelledInputController {
|
|
11
11
|
constructor(input, labelController) {
|
|
12
12
|
this.input = input;
|
|
13
|
-
this.__preventDuplicateLabelClick = this.__preventDuplicateLabelClick.bind(this);
|
|
14
13
|
|
|
15
14
|
labelController.addEventListener('slot-content-changed', (event) => {
|
|
16
|
-
this
|
|
15
|
+
this.#initLabel(event.detail.node);
|
|
17
16
|
});
|
|
18
17
|
|
|
19
18
|
// Initialize the default label element
|
|
20
|
-
this
|
|
19
|
+
this.#initLabel(labelController.node);
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
/**
|
|
24
23
|
* @param {HTMLElement} label
|
|
25
|
-
* @private
|
|
26
24
|
*/
|
|
27
|
-
|
|
25
|
+
#initLabel(label) {
|
|
28
26
|
if (label) {
|
|
29
|
-
label.addEventListener('click', this
|
|
27
|
+
label.addEventListener('click', this.#preventDuplicateLabelClick);
|
|
30
28
|
|
|
31
29
|
if (this.input) {
|
|
32
30
|
label.setAttribute('for', this.input.id);
|
|
@@ -40,13 +38,12 @@ export class LabelledInputController {
|
|
|
40
38
|
* This results in two click events arriving at the host, but we only want one.
|
|
41
39
|
* This method prevents the duplicate click and ensures the correct isTrusted event
|
|
42
40
|
* with the correct event.target arrives at the host.
|
|
43
|
-
* @private
|
|
44
41
|
*/
|
|
45
|
-
|
|
42
|
+
#preventDuplicateLabelClick = () => {
|
|
46
43
|
const inputClickHandler = (e) => {
|
|
47
44
|
e.stopImmediatePropagation();
|
|
48
45
|
this.input.removeEventListener('click', inputClickHandler);
|
|
49
46
|
};
|
|
50
47
|
this.input.addEventListener('click', inputClickHandler);
|
|
51
|
-
}
|
|
48
|
+
};
|
|
52
49
|
}
|
|
@@ -18,10 +18,6 @@ export const checkable = (part, propName = part) => css`
|
|
|
18
18
|
--_cursor: var(--vaadin-clickable-cursor);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
:host([disabled]) {
|
|
22
|
-
--_cursor: var(--vaadin-disabled-cursor);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
21
|
:host(:not([has-label])) {
|
|
26
22
|
column-gap: 0;
|
|
27
23
|
}
|
|
@@ -41,7 +37,6 @@ export const checkable = (part, propName = part) => css`
|
|
|
41
37
|
color: var(--vaadin-${unsafeCSS(propName)}-label-color, var(--vaadin-input-field-label-color, var(--vaadin-text-color)));
|
|
42
38
|
word-break: break-word;
|
|
43
39
|
cursor: var(--_cursor);
|
|
44
|
-
/* TODO clicking the label part doesn't toggle the checked state, even though it triggers the active state */
|
|
45
40
|
}
|
|
46
41
|
|
|
47
42
|
[part='${unsafeCSS(part)}'],
|
|
@@ -95,8 +90,8 @@ export const checkable = (part, propName = part) => css`
|
|
|
95
90
|
box-sizing: border-box;
|
|
96
91
|
--_color: var(--vaadin-${unsafeCSS(propName)}-marker-color, var(--vaadin-${unsafeCSS(propName)}-background, var(--vaadin-background-color)));
|
|
97
92
|
color: var(--_color);
|
|
98
|
-
height: var(--vaadin-${unsafeCSS(propName)}-size,
|
|
99
|
-
width: var(--vaadin-${unsafeCSS(propName)}-size,
|
|
93
|
+
height: var(--vaadin-${unsafeCSS(propName)}-size, round(1.125em, 2px));
|
|
94
|
+
width: var(--vaadin-${unsafeCSS(propName)}-size, round(1.125em, 2px));
|
|
100
95
|
position: relative;
|
|
101
96
|
cursor: var(--_cursor);
|
|
102
97
|
display: flex;
|
|
@@ -109,10 +104,24 @@ export const checkable = (part, propName = part) => css`
|
|
|
109
104
|
--vaadin-${unsafeCSS(propName)}-border-color: transparent;
|
|
110
105
|
}
|
|
111
106
|
|
|
107
|
+
:host([readonly]) {
|
|
108
|
+
--vaadin-${unsafeCSS(part)}-background: transparent;
|
|
109
|
+
--vaadin-${unsafeCSS(part)}-border-color: var(--vaadin-border-color);
|
|
110
|
+
--vaadin-${unsafeCSS(part)}-marker-color: var(--vaadin-text-color);
|
|
111
|
+
--_border-style: dashed;
|
|
112
|
+
--_cursor: var(--vaadin-disabled-cursor);
|
|
113
|
+
|
|
114
|
+
[part='label'],
|
|
115
|
+
::slotted(label) {
|
|
116
|
+
cursor: default;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
112
120
|
:host([disabled]) {
|
|
113
121
|
--vaadin-${unsafeCSS(propName)}-background: var(--vaadin-input-field-disabled-background, var(--vaadin-background-container-strong));
|
|
114
122
|
--vaadin-${unsafeCSS(propName)}-border-color: transparent;
|
|
115
123
|
--vaadin-${unsafeCSS(propName)}-marker-color: var(--vaadin-text-color-disabled);
|
|
124
|
+
--_cursor: var(--vaadin-disabled-cursor);
|
|
116
125
|
}
|
|
117
126
|
|
|
118
127
|
/* Focus ring */
|
|
@@ -146,6 +155,30 @@ export const checkable = (part, propName = part) => css`
|
|
|
146
155
|
opacity: 0;
|
|
147
156
|
}
|
|
148
157
|
|
|
158
|
+
/* Reverse variant */
|
|
159
|
+
:host([theme~='reverse']) {
|
|
160
|
+
grid-template-columns: 1fr auto;
|
|
161
|
+
|
|
162
|
+
&::before {
|
|
163
|
+
display: none;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
[part='label'],
|
|
167
|
+
[part='helper-text'],
|
|
168
|
+
[part='error-message'] {
|
|
169
|
+
grid-column: 1;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
[part='${unsafeCSS(part)}'],
|
|
173
|
+
::slotted(input) {
|
|
174
|
+
grid-column: 2;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
::slotted(input) {
|
|
178
|
+
margin-inline: calc(min(0px, (24px - 100%) / -2) - var(--vaadin-${unsafeCSS(propName)}-gap, var(--vaadin-gap-s))) 0 !important;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
149
182
|
@media (forced-colors: active) {
|
|
150
183
|
:host(:is([checked], [indeterminate])) {
|
|
151
184
|
--vaadin-${unsafeCSS(propName)}-border-color: CanvasText !important;
|
|
@@ -18,19 +18,18 @@ export class VirtualKeyboardController {
|
|
|
18
18
|
host.addEventListener('opened-changed', () => {
|
|
19
19
|
if (!host.opened) {
|
|
20
20
|
// Prevent opening the virtual keyboard when the input gets re-focused on dropdown close
|
|
21
|
-
this
|
|
21
|
+
this.#setVirtualKeyboardEnabled(false);
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
// Re-enable virtual keyboard on blur, so it gets opened when the field is focused again
|
|
26
|
-
host.addEventListener('blur', () => this
|
|
26
|
+
host.addEventListener('blur', () => this.#setVirtualKeyboardEnabled(true));
|
|
27
27
|
|
|
28
28
|
// Re-enable the virtual keyboard whenever the field is touched
|
|
29
|
-
host.addEventListener('touchstart', () => this
|
|
29
|
+
host.addEventListener('touchstart', () => this.#setVirtualKeyboardEnabled(true));
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
__setVirtualKeyboardEnabled(value) {
|
|
32
|
+
#setVirtualKeyboardEnabled(value) {
|
|
34
33
|
if (this.host.inputElement) {
|
|
35
34
|
this.host.inputElement.inputMode = value ? '' : 'none';
|
|
36
35
|
}
|