@vaadin/checkbox-group 22.0.0-alpha5 → 22.0.0-alpha9
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,10 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/checkbox-group",
|
|
3
|
-
"version": "22.0.0-
|
|
3
|
+
"version": "22.0.0-alpha9",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
4
7
|
"description": "vaadin-checkbox-group",
|
|
8
|
+
"license": "Apache-2.0",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/vaadin/web-components.git",
|
|
12
|
+
"directory": "packages/checkbox-group"
|
|
13
|
+
},
|
|
14
|
+
"author": "Vaadin Ltd",
|
|
15
|
+
"homepage": "https://vaadin.com/components",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/vaadin/web-components/issues"
|
|
18
|
+
},
|
|
5
19
|
"main": "vaadin-checkbox-group.js",
|
|
6
20
|
"module": "vaadin-checkbox-group.js",
|
|
7
|
-
"
|
|
21
|
+
"files": [
|
|
22
|
+
"src",
|
|
23
|
+
"theme",
|
|
24
|
+
"vaadin-*.d.ts",
|
|
25
|
+
"vaadin-*.js"
|
|
26
|
+
],
|
|
8
27
|
"keywords": [
|
|
9
28
|
"Vaadin",
|
|
10
29
|
"checkbox",
|
|
@@ -12,33 +31,18 @@
|
|
|
12
31
|
"web-component",
|
|
13
32
|
"polymer"
|
|
14
33
|
],
|
|
15
|
-
"author": "Vaadin Ltd",
|
|
16
|
-
"license": "Apache-2.0",
|
|
17
|
-
"bugs": {
|
|
18
|
-
"url": "https://github.com/vaadin/web-components/issues"
|
|
19
|
-
},
|
|
20
|
-
"homepage": "https://vaadin.com/components",
|
|
21
|
-
"files": [
|
|
22
|
-
"vaadin-*.d.ts",
|
|
23
|
-
"vaadin-*.js",
|
|
24
|
-
"src",
|
|
25
|
-
"theme"
|
|
26
|
-
],
|
|
27
34
|
"dependencies": {
|
|
28
35
|
"@polymer/polymer": "^3.0.0",
|
|
29
|
-
"@vaadin/checkbox": "
|
|
30
|
-
"@vaadin/
|
|
31
|
-
"@vaadin/vaadin-lumo-styles": "
|
|
32
|
-
"@vaadin/vaadin-material-styles": "
|
|
33
|
-
"@vaadin/vaadin-themable-mixin": "
|
|
36
|
+
"@vaadin/checkbox": "22.0.0-alpha9",
|
|
37
|
+
"@vaadin/component-base": "22.0.0-alpha9",
|
|
38
|
+
"@vaadin/vaadin-lumo-styles": "22.0.0-alpha9",
|
|
39
|
+
"@vaadin/vaadin-material-styles": "22.0.0-alpha9",
|
|
40
|
+
"@vaadin/vaadin-themable-mixin": "22.0.0-alpha9"
|
|
34
41
|
},
|
|
35
42
|
"devDependencies": {
|
|
36
43
|
"@esm-bundle/chai": "^4.3.4",
|
|
37
|
-
"@vaadin/testing-helpers": "^0.
|
|
44
|
+
"@vaadin/testing-helpers": "^0.3.0",
|
|
38
45
|
"sinon": "^9.2.0"
|
|
39
46
|
},
|
|
40
|
-
"
|
|
41
|
-
"access": "public"
|
|
42
|
-
},
|
|
43
|
-
"gitHead": "012f658db6f81375be8889f63ee15e3f660fe9ec"
|
|
47
|
+
"gitHead": "6e8c899dc65918f97e3c0acb2076122c4b2ef274"
|
|
44
48
|
}
|
|
@@ -1,9 +1,14 @@
|
|
|
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 { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
|
|
7
|
+
import { DisabledMixin } from '@vaadin/component-base/src/disabled-mixin.js';
|
|
8
|
+
import { FocusMixin } from '@vaadin/component-base/src/focus-mixin.js';
|
|
9
|
+
import { FieldMixin } from '@vaadin/field-base/src/field-mixin.js';
|
|
1
10
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
2
11
|
|
|
3
|
-
import { DirMixin } from '@vaadin/vaadin-element-mixin/vaadin-dir-mixin.js';
|
|
4
|
-
|
|
5
|
-
import { CheckboxElement } from '@vaadin/checkbox/src/vaadin-checkbox.js';
|
|
6
|
-
|
|
7
12
|
/**
|
|
8
13
|
* Fired when the `invalid` property changes.
|
|
9
14
|
*/
|
|
@@ -14,16 +19,16 @@ export type CheckboxGroupInvalidChangedEvent = CustomEvent<{ value: boolean }>;
|
|
|
14
19
|
*/
|
|
15
20
|
export type CheckboxGroupValueChangedEvent = CustomEvent<{ value: Array<string> }>;
|
|
16
21
|
|
|
17
|
-
export interface
|
|
22
|
+
export interface CheckboxGroupCustomEventMap {
|
|
18
23
|
'invalid-changed': CheckboxGroupInvalidChangedEvent;
|
|
19
24
|
|
|
20
25
|
'value-changed': CheckboxGroupValueChangedEvent;
|
|
21
26
|
}
|
|
22
27
|
|
|
23
|
-
export interface CheckboxGroupEventMap extends HTMLElementEventMap,
|
|
28
|
+
export interface CheckboxGroupEventMap extends HTMLElementEventMap, CheckboxGroupCustomEventMap {}
|
|
24
29
|
|
|
25
30
|
/**
|
|
26
|
-
* `<vaadin-checkbox-group>` is a
|
|
31
|
+
* `<vaadin-checkbox-group>` is a web component that allows the user to choose several items from a group of binary choices.
|
|
27
32
|
*
|
|
28
33
|
* ```html
|
|
29
34
|
* <vaadin-checkbox-group label="Preferred language of contact:">
|
|
@@ -37,105 +42,57 @@ export interface CheckboxGroupEventMap extends HTMLElementEventMap, CheckboxGrou
|
|
|
37
42
|
*
|
|
38
43
|
* The following shadow DOM parts are available for styling:
|
|
39
44
|
*
|
|
40
|
-
* Part name
|
|
41
|
-
*
|
|
42
|
-
* `label`
|
|
43
|
-
* `group-field`
|
|
44
|
-
* `
|
|
45
|
+
* Part name | Description
|
|
46
|
+
* ---------------------|----------------
|
|
47
|
+
* `label` | The slotted label element wrapper
|
|
48
|
+
* `group-field` | The checkbox elements wrapper
|
|
49
|
+
* `helper-text` | The slotted helper text element wrapper
|
|
50
|
+
* `error-message` | The slotted error message element wrapper
|
|
51
|
+
* `required-indicator` | The `required` state indicator element
|
|
45
52
|
*
|
|
46
53
|
* The following state attributes are available for styling:
|
|
47
54
|
*
|
|
48
|
-
* Attribute
|
|
49
|
-
*
|
|
50
|
-
* `disabled`
|
|
51
|
-
* `
|
|
52
|
-
* `
|
|
53
|
-
* `has-
|
|
54
|
-
* `has-
|
|
55
|
-
* `has-
|
|
56
|
-
* `
|
|
57
|
-
* `invalid` | Set when the element is invalid | :host
|
|
55
|
+
* Attribute | Description | Part name
|
|
56
|
+
* --------------------|-------------------------------------------|------------
|
|
57
|
+
* `disabled` | Set when the element is disabled | :host
|
|
58
|
+
* `invalid` | Set when the element is invalid | :host
|
|
59
|
+
* `focused` | Set when the element is focused | :host
|
|
60
|
+
* `has-label` | Set when the element has a label | :host
|
|
61
|
+
* `has-value` | Set when the element has a value | :host
|
|
62
|
+
* `has-helper` | Set when the element has helper text | :host
|
|
63
|
+
* `has-error-message` | Set when the element has an error message | :host
|
|
58
64
|
*
|
|
59
65
|
* See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
|
|
60
66
|
*
|
|
61
67
|
* @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
|
|
62
68
|
* @fires {CustomEvent} value-changed - Fired when the `value` property changes.
|
|
63
69
|
*/
|
|
64
|
-
declare class
|
|
70
|
+
declare class CheckboxGroup extends FieldMixin(FocusMixin(DisabledMixin(DirMixin(ThemableMixin(HTMLElement))))) {
|
|
65
71
|
/**
|
|
66
|
-
* The
|
|
67
|
-
*/
|
|
68
|
-
disabled: boolean | null | undefined;
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* String used for the label element.
|
|
72
|
-
*/
|
|
73
|
-
label: string | null | undefined;
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Value of the checkbox group.
|
|
72
|
+
* The value of the checkbox group.
|
|
77
73
|
* Note: toggling the checkboxes modifies the value by creating new
|
|
78
74
|
* array each time, to override Polymer dirty-checking for arrays.
|
|
79
75
|
* You can still use Polymer array mutation methods to update the value.
|
|
80
76
|
*/
|
|
81
77
|
value: string[];
|
|
82
78
|
|
|
83
|
-
/**
|
|
84
|
-
* Error to show when the input value is invalid.
|
|
85
|
-
* @attr {string} error-message
|
|
86
|
-
*/
|
|
87
|
-
errorMessage: string | null | undefined;
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* String used for the helper text.
|
|
91
|
-
* @attr {string} helper-text
|
|
92
|
-
*/
|
|
93
|
-
helperText: string | null;
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Specifies that the user must fill in a value.
|
|
97
|
-
*/
|
|
98
|
-
required: boolean | null | undefined;
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* This property is set to true when the control value is invalid.
|
|
102
|
-
*/
|
|
103
|
-
invalid: boolean;
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Returns true if `value` is valid.
|
|
107
|
-
*
|
|
108
|
-
* @returns True if the value is valid.
|
|
109
|
-
*/
|
|
110
|
-
validate(): boolean;
|
|
111
|
-
|
|
112
|
-
_addCheckboxToValue(value: string): void;
|
|
113
|
-
|
|
114
|
-
_removeCheckboxFromValue(value: string): void;
|
|
115
|
-
|
|
116
|
-
_changeSelectedCheckbox(checkbox: CheckboxElement | null): void;
|
|
117
|
-
|
|
118
|
-
_containsFocus(): boolean;
|
|
119
|
-
|
|
120
|
-
_setFocused(focused: boolean): void;
|
|
121
|
-
|
|
122
79
|
addEventListener<K extends keyof CheckboxGroupEventMap>(
|
|
123
80
|
type: K,
|
|
124
|
-
listener: (this:
|
|
81
|
+
listener: (this: CheckboxGroup, ev: CheckboxGroupEventMap[K]) => void,
|
|
125
82
|
options?: boolean | AddEventListenerOptions
|
|
126
83
|
): void;
|
|
127
84
|
|
|
128
85
|
removeEventListener<K extends keyof CheckboxGroupEventMap>(
|
|
129
86
|
type: K,
|
|
130
|
-
listener: (this:
|
|
87
|
+
listener: (this: CheckboxGroup, ev: CheckboxGroupEventMap[K]) => void,
|
|
131
88
|
options?: boolean | EventListenerOptions
|
|
132
89
|
): void;
|
|
133
90
|
}
|
|
134
91
|
|
|
135
92
|
declare global {
|
|
136
93
|
interface HTMLElementTagNameMap {
|
|
137
|
-
'vaadin-checkbox-group':
|
|
94
|
+
'vaadin-checkbox-group': CheckboxGroup;
|
|
138
95
|
}
|
|
139
96
|
}
|
|
140
97
|
|
|
141
|
-
export {
|
|
98
|
+
export { CheckboxGroup };
|
|
@@ -5,12 +5,15 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
|
|
7
7
|
import { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js';
|
|
8
|
+
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
|
|
9
|
+
import { DisabledMixin } from '@vaadin/component-base/src/disabled-mixin.js';
|
|
10
|
+
import { FocusMixin } from '@vaadin/component-base/src/focus-mixin.js';
|
|
11
|
+
import { FieldMixin } from '@vaadin/field-base/src/field-mixin.js';
|
|
8
12
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
9
|
-
import {
|
|
10
|
-
import { CheckboxElement } from '@vaadin/checkbox/src/vaadin-checkbox.js';
|
|
13
|
+
import { Checkbox } from '@vaadin/checkbox/src/vaadin-checkbox.js';
|
|
11
14
|
|
|
12
15
|
/**
|
|
13
|
-
* `<vaadin-checkbox-group>` is a
|
|
16
|
+
* `<vaadin-checkbox-group>` is a web component that allows the user to choose several items from a group of binary choices.
|
|
14
17
|
*
|
|
15
18
|
* ```html
|
|
16
19
|
* <vaadin-checkbox-group label="Preferred language of contact:">
|
|
@@ -24,24 +27,25 @@ import { CheckboxElement } from '@vaadin/checkbox/src/vaadin-checkbox.js';
|
|
|
24
27
|
*
|
|
25
28
|
* The following shadow DOM parts are available for styling:
|
|
26
29
|
*
|
|
27
|
-
* Part name
|
|
28
|
-
*
|
|
29
|
-
* `label`
|
|
30
|
-
* `group-field`
|
|
31
|
-
* `
|
|
30
|
+
* Part name | Description
|
|
31
|
+
* ---------------------|----------------
|
|
32
|
+
* `label` | The slotted label element wrapper
|
|
33
|
+
* `group-field` | The checkbox elements wrapper
|
|
34
|
+
* `helper-text` | The slotted helper text element wrapper
|
|
35
|
+
* `error-message` | The slotted error message element wrapper
|
|
36
|
+
* `required-indicator` | The `required` state indicator element
|
|
32
37
|
*
|
|
33
38
|
* The following state attributes are available for styling:
|
|
34
39
|
*
|
|
35
|
-
* Attribute
|
|
36
|
-
*
|
|
37
|
-
* `disabled`
|
|
38
|
-
* `
|
|
39
|
-
* `
|
|
40
|
-
* `has-
|
|
41
|
-
* `has-
|
|
42
|
-
* `has-
|
|
43
|
-
* `
|
|
44
|
-
* `invalid` | Set when the element is invalid | :host
|
|
40
|
+
* Attribute | Description | Part name
|
|
41
|
+
* --------------------|-------------------------------------------|------------
|
|
42
|
+
* `disabled` | Set when the element is disabled | :host
|
|
43
|
+
* `invalid` | Set when the element is invalid | :host
|
|
44
|
+
* `focused` | Set when the element is focused | :host
|
|
45
|
+
* `has-label` | Set when the element has a label | :host
|
|
46
|
+
* `has-value` | Set when the element has a value | :host
|
|
47
|
+
* `has-helper` | Set when the element has helper text | :host
|
|
48
|
+
* `has-error-message` | Set when the element has an error message | :host
|
|
45
49
|
*
|
|
46
50
|
* See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
|
|
47
51
|
*
|
|
@@ -51,9 +55,15 @@ import { CheckboxElement } from '@vaadin/checkbox/src/vaadin-checkbox.js';
|
|
|
51
55
|
* @extends HTMLElement
|
|
52
56
|
* @mixes ThemableMixin
|
|
53
57
|
* @mixes DirMixin
|
|
54
|
-
* @
|
|
58
|
+
* @mixes DisabledMixin
|
|
59
|
+
* @mixes FocusMixin
|
|
60
|
+
* @mixes FieldMixin
|
|
55
61
|
*/
|
|
56
|
-
class
|
|
62
|
+
class CheckboxGroup extends FieldMixin(FocusMixin(DisabledMixin(DirMixin(ThemableMixin(PolymerElement))))) {
|
|
63
|
+
static get is() {
|
|
64
|
+
return 'vaadin-checkbox-group';
|
|
65
|
+
}
|
|
66
|
+
|
|
57
67
|
static get template() {
|
|
58
68
|
return html`
|
|
59
69
|
<style>
|
|
@@ -76,62 +86,36 @@ class CheckboxGroupElement extends ThemableMixin(DirMixin(PolymerElement)) {
|
|
|
76
86
|
flex-direction: column;
|
|
77
87
|
}
|
|
78
88
|
|
|
79
|
-
[part='label']
|
|
89
|
+
:host(:not([has-label])) [part='label'] {
|
|
80
90
|
display: none;
|
|
81
91
|
}
|
|
82
92
|
</style>
|
|
83
93
|
|
|
84
94
|
<div class="vaadin-group-field-container">
|
|
85
|
-
<
|
|
95
|
+
<div part="label">
|
|
96
|
+
<slot name="label"></slot>
|
|
97
|
+
<span part="required-indicator" aria-hidden="true"></span>
|
|
98
|
+
</div>
|
|
86
99
|
|
|
87
100
|
<div part="group-field">
|
|
88
|
-
<slot
|
|
101
|
+
<slot></slot>
|
|
89
102
|
</div>
|
|
90
103
|
|
|
91
|
-
<div
|
|
92
|
-
|
|
93
|
-
aria-live="assertive"
|
|
94
|
-
aria-hidden$="[[_getHelperTextAriaHidden(helperText, _hasSlottedHelper)]]"
|
|
95
|
-
>
|
|
96
|
-
<slot name="helper">[[helperText]]</slot>
|
|
104
|
+
<div part="helper-text">
|
|
105
|
+
<slot name="helper"></slot>
|
|
97
106
|
</div>
|
|
98
107
|
|
|
99
|
-
<div
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
aria-hidden$="[[_getErrorMessageAriaHidden(invalid, errorMessage)]]"
|
|
103
|
-
>[[errorMessage]]</div
|
|
104
|
-
>
|
|
108
|
+
<div part="error-message">
|
|
109
|
+
<slot name="error-message"></slot>
|
|
110
|
+
</div>
|
|
105
111
|
</div>
|
|
106
112
|
`;
|
|
107
113
|
}
|
|
108
114
|
|
|
109
|
-
static get is() {
|
|
110
|
-
return 'vaadin-checkbox-group';
|
|
111
|
-
}
|
|
112
|
-
|
|
113
115
|
static get properties() {
|
|
114
116
|
return {
|
|
115
117
|
/**
|
|
116
|
-
* The
|
|
117
|
-
*/
|
|
118
|
-
disabled: {
|
|
119
|
-
type: Boolean,
|
|
120
|
-
reflectToAttribute: true,
|
|
121
|
-
observer: '_disabledChanged'
|
|
122
|
-
},
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* String used for the label element.
|
|
126
|
-
*/
|
|
127
|
-
label: {
|
|
128
|
-
type: String,
|
|
129
|
-
value: '',
|
|
130
|
-
observer: '_labelChanged'
|
|
131
|
-
},
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Value of the checkbox group.
|
|
118
|
+
* The value of the checkbox group.
|
|
135
119
|
* Note: toggling the checkboxes modifies the value by creating new
|
|
136
120
|
* array each time, to override Polymer dirty-checking for arrays.
|
|
137
121
|
* You can still use Polymer array mutation methods to update the value.
|
|
@@ -141,269 +125,241 @@ class CheckboxGroupElement extends ThemableMixin(DirMixin(PolymerElement)) {
|
|
|
141
125
|
type: Array,
|
|
142
126
|
value: () => [],
|
|
143
127
|
notify: true
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Error to show when the input value is invalid.
|
|
148
|
-
* @attr {string} error-message
|
|
149
|
-
*/
|
|
150
|
-
errorMessage: {
|
|
151
|
-
type: String,
|
|
152
|
-
value: '',
|
|
153
|
-
observer: '_errorMessageChanged'
|
|
154
|
-
},
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* String used for the helper text.
|
|
158
|
-
* @attr {string} helper-text
|
|
159
|
-
* @type {string | null}
|
|
160
|
-
*/
|
|
161
|
-
helperText: {
|
|
162
|
-
type: String,
|
|
163
|
-
value: '',
|
|
164
|
-
observer: '_helperTextChanged'
|
|
165
|
-
},
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Specifies that the user must fill in a value.
|
|
169
|
-
*/
|
|
170
|
-
required: {
|
|
171
|
-
type: Boolean,
|
|
172
|
-
reflectToAttribute: true
|
|
173
|
-
},
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* This property is set to true when the control value is invalid.
|
|
177
|
-
* @type {boolean}
|
|
178
|
-
*/
|
|
179
|
-
invalid: {
|
|
180
|
-
type: Boolean,
|
|
181
|
-
reflectToAttribute: true,
|
|
182
|
-
notify: true,
|
|
183
|
-
value: false
|
|
184
|
-
},
|
|
185
|
-
|
|
186
|
-
/** @private */
|
|
187
|
-
_hasSlottedHelper: Boolean
|
|
128
|
+
}
|
|
188
129
|
};
|
|
189
130
|
}
|
|
190
131
|
|
|
191
132
|
static get observers() {
|
|
192
|
-
return ['
|
|
133
|
+
return ['__valueChanged(value, value.splices)'];
|
|
193
134
|
}
|
|
194
135
|
|
|
195
|
-
|
|
196
|
-
super
|
|
136
|
+
constructor() {
|
|
137
|
+
super();
|
|
197
138
|
|
|
198
|
-
this.
|
|
199
|
-
|
|
200
|
-
this.
|
|
201
|
-
|
|
202
|
-
if (
|
|
203
|
-
!this._checkboxes.some(
|
|
204
|
-
(checkbox) => e.relatedTarget === checkbox || checkbox.shadowRoot.contains(e.relatedTarget)
|
|
205
|
-
)
|
|
206
|
-
) {
|
|
207
|
-
this.validate();
|
|
208
|
-
this._setFocused(false);
|
|
209
|
-
}
|
|
210
|
-
});
|
|
139
|
+
this.__registerCheckbox = this.__registerCheckbox.bind(this);
|
|
140
|
+
this.__unregisterCheckbox = this.__unregisterCheckbox.bind(this);
|
|
141
|
+
this.__onCheckboxCheckedChanged = this.__onCheckboxCheckedChanged.bind(this);
|
|
142
|
+
}
|
|
211
143
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
};
|
|
144
|
+
ready() {
|
|
145
|
+
super.ready();
|
|
215
146
|
|
|
216
|
-
this.
|
|
217
|
-
const addedCheckboxes = this._filterCheckboxes(info.addedNodes);
|
|
147
|
+
this.ariaTarget = this;
|
|
218
148
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
if (this.disabled) {
|
|
222
|
-
checkbox.disabled = true;
|
|
223
|
-
}
|
|
224
|
-
if (checkbox.checked) {
|
|
225
|
-
this._addCheckboxToValue(checkbox.value);
|
|
226
|
-
} else if (this.value.indexOf(checkbox.value) > -1) {
|
|
227
|
-
checkbox.checked = true;
|
|
228
|
-
}
|
|
229
|
-
});
|
|
149
|
+
// See https://github.com/vaadin/vaadin-web-components/issues/94
|
|
150
|
+
this.setAttribute('role', 'group');
|
|
230
151
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
this._removeCheckboxFromValue(checkbox.value);
|
|
235
|
-
}
|
|
236
|
-
});
|
|
152
|
+
this._observer = new FlattenedNodesObserver(this, ({ addedNodes, removedNodes }) => {
|
|
153
|
+
const addedCheckboxes = this.__filterCheckboxes(addedNodes);
|
|
154
|
+
const removedCheckboxes = this.__filterCheckboxes(removedNodes);
|
|
237
155
|
|
|
238
|
-
this.
|
|
156
|
+
addedCheckboxes.forEach(this.__registerCheckbox);
|
|
157
|
+
removedCheckboxes.forEach(this.__unregisterCheckbox);
|
|
239
158
|
|
|
240
|
-
|
|
241
|
-
const { value } = checkbox;
|
|
242
|
-
return checkbox.hasAttribute('value') || (value && value !== 'on');
|
|
243
|
-
};
|
|
244
|
-
if (!addedCheckboxes.every(hasValue)) {
|
|
245
|
-
console.warn('Please add value attribute to all checkboxes in checkbox group');
|
|
246
|
-
}
|
|
159
|
+
this.__warnOfCheckboxesWithoutValue(addedCheckboxes);
|
|
247
160
|
});
|
|
248
161
|
}
|
|
249
162
|
|
|
250
163
|
/**
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
* @
|
|
164
|
+
* @return {string}
|
|
165
|
+
* @override
|
|
166
|
+
* @protected
|
|
254
167
|
*/
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
return !this.invalid;
|
|
168
|
+
get _ariaAttr() {
|
|
169
|
+
return 'aria-labelledby';
|
|
258
170
|
}
|
|
259
171
|
|
|
260
|
-
/**
|
|
261
|
-
|
|
262
|
-
|
|
172
|
+
/**
|
|
173
|
+
* Override method inherited from `ValidateMixin`
|
|
174
|
+
* to validate the value array.
|
|
175
|
+
*
|
|
176
|
+
* @override
|
|
177
|
+
* @return {boolean}
|
|
178
|
+
*/
|
|
179
|
+
checkValidity() {
|
|
180
|
+
return !this.required || this.value.length > 0;
|
|
263
181
|
}
|
|
264
182
|
|
|
265
|
-
/**
|
|
266
|
-
|
|
267
|
-
|
|
183
|
+
/**
|
|
184
|
+
* @param {!Array<!Node>} nodes
|
|
185
|
+
* @return {!Array<!Checkbox>}
|
|
186
|
+
* @private
|
|
187
|
+
*/
|
|
188
|
+
__filterCheckboxes(nodes) {
|
|
189
|
+
return nodes.filter((child) => child instanceof Checkbox);
|
|
268
190
|
}
|
|
269
191
|
|
|
270
|
-
/**
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
192
|
+
/**
|
|
193
|
+
* A collection of the checkboxes.
|
|
194
|
+
*
|
|
195
|
+
* @return {!Array<!Checkbox>}
|
|
196
|
+
* @private
|
|
197
|
+
*/
|
|
198
|
+
get __checkboxes() {
|
|
199
|
+
return this.__filterCheckboxes([...this.children]);
|
|
275
200
|
}
|
|
276
201
|
|
|
277
202
|
/**
|
|
278
|
-
* @param {
|
|
279
|
-
* @
|
|
203
|
+
* @param {!Array<!Checkbox>} checkboxes
|
|
204
|
+
* @private
|
|
280
205
|
*/
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
206
|
+
__warnOfCheckboxesWithoutValue(checkboxes) {
|
|
207
|
+
const hasCheckboxesWithoutValue = checkboxes.some((checkbox) => {
|
|
208
|
+
const { value } = checkbox;
|
|
209
|
+
|
|
210
|
+
return !checkbox.hasAttribute('value') && (!value || value === 'on');
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
if (hasCheckboxesWithoutValue) {
|
|
214
|
+
console.warn('Please provide the value attribute to all the checkboxes inside the checkbox group.');
|
|
284
215
|
}
|
|
285
216
|
}
|
|
286
217
|
|
|
287
218
|
/**
|
|
288
|
-
*
|
|
289
|
-
*
|
|
219
|
+
* Registers the checkbox after adding it to the group.
|
|
220
|
+
*
|
|
221
|
+
* @param {!Checkbox} checkbox
|
|
222
|
+
* @private
|
|
290
223
|
*/
|
|
291
|
-
|
|
292
|
-
|
|
224
|
+
__registerCheckbox(checkbox) {
|
|
225
|
+
checkbox.addEventListener('checked-changed', this.__onCheckboxCheckedChanged);
|
|
226
|
+
|
|
227
|
+
if (this.disabled) {
|
|
228
|
+
checkbox.disabled = true;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (checkbox.checked) {
|
|
232
|
+
this.__addCheckboxToValue(checkbox.value);
|
|
233
|
+
} else if (this.value.includes(checkbox.value)) {
|
|
234
|
+
checkbox.checked = true;
|
|
235
|
+
}
|
|
293
236
|
}
|
|
294
237
|
|
|
295
238
|
/**
|
|
296
|
-
*
|
|
297
|
-
*
|
|
239
|
+
* Unregisters the checkbox before removing it from the group.
|
|
240
|
+
*
|
|
241
|
+
* @param {!Checkbox} checkbox
|
|
242
|
+
* @private
|
|
298
243
|
*/
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
return;
|
|
302
|
-
}
|
|
244
|
+
__unregisterCheckbox(checkbox) {
|
|
245
|
+
checkbox.removeEventListener('checked-changed', this.__onCheckboxCheckedChanged);
|
|
303
246
|
|
|
304
247
|
if (checkbox.checked) {
|
|
305
|
-
this.
|
|
306
|
-
} else {
|
|
307
|
-
this._removeCheckboxFromValue(checkbox.value);
|
|
248
|
+
this.__removeCheckboxFromValue(checkbox.value);
|
|
308
249
|
}
|
|
309
250
|
}
|
|
310
251
|
|
|
311
|
-
/**
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
252
|
+
/**
|
|
253
|
+
* Override method inherited from `DisabledMixin`
|
|
254
|
+
* to propagate the `disabled` property to the checkboxes.
|
|
255
|
+
*
|
|
256
|
+
* @param {boolean} newValue
|
|
257
|
+
* @param {boolean} oldValue
|
|
258
|
+
* @override
|
|
259
|
+
* @protected
|
|
260
|
+
*/
|
|
261
|
+
_disabledChanged(newValue, oldValue) {
|
|
262
|
+
super._disabledChanged(newValue, oldValue);
|
|
263
|
+
|
|
264
|
+
// Prevent updating the `disabled` property for the checkboxes at initialization.
|
|
265
|
+
// Otherwise, the checkboxes may end up enabled regardless the `disabled` attribute
|
|
266
|
+
// intentionally added by the user on some of them.
|
|
267
|
+
if (!newValue && oldValue === undefined) {
|
|
315
268
|
return;
|
|
316
269
|
}
|
|
317
270
|
|
|
318
|
-
if (
|
|
319
|
-
this.
|
|
320
|
-
|
|
321
|
-
|
|
271
|
+
if (oldValue !== newValue) {
|
|
272
|
+
this.__checkboxes.forEach((checkbox) => {
|
|
273
|
+
checkbox.disabled = newValue;
|
|
274
|
+
});
|
|
322
275
|
}
|
|
323
|
-
|
|
324
|
-
this._oldValue = value;
|
|
325
|
-
// set a flag to avoid updating loop
|
|
326
|
-
this._updatingValue = true;
|
|
327
|
-
// reflect the value array to checkboxes
|
|
328
|
-
this._checkboxes.forEach((checkbox) => {
|
|
329
|
-
checkbox.checked = value.indexOf(checkbox.value) > -1;
|
|
330
|
-
});
|
|
331
|
-
this._updatingValue = false;
|
|
332
|
-
|
|
333
|
-
this.validate();
|
|
334
276
|
}
|
|
335
277
|
|
|
336
|
-
/**
|
|
337
|
-
|
|
338
|
-
|
|
278
|
+
/**
|
|
279
|
+
* @param {string} value
|
|
280
|
+
* @private
|
|
281
|
+
*/
|
|
282
|
+
__addCheckboxToValue(value) {
|
|
283
|
+
if (!this.value.includes(value)) {
|
|
284
|
+
this.value = [...this.value, value];
|
|
285
|
+
}
|
|
339
286
|
}
|
|
340
287
|
|
|
341
|
-
/**
|
|
342
|
-
|
|
343
|
-
|
|
288
|
+
/**
|
|
289
|
+
* @param {string} value
|
|
290
|
+
* @private
|
|
291
|
+
*/
|
|
292
|
+
__removeCheckboxFromValue(value) {
|
|
293
|
+
if (this.value.includes(value)) {
|
|
294
|
+
this.value = this.value.filter((v) => v !== value);
|
|
295
|
+
}
|
|
344
296
|
}
|
|
345
297
|
|
|
346
|
-
/**
|
|
347
|
-
|
|
348
|
-
|
|
298
|
+
/**
|
|
299
|
+
* @param {!CustomEvent} event
|
|
300
|
+
* @private
|
|
301
|
+
*/
|
|
302
|
+
__onCheckboxCheckedChanged(event) {
|
|
303
|
+
const checkbox = event.target;
|
|
304
|
+
|
|
305
|
+
if (checkbox.checked) {
|
|
306
|
+
this.__addCheckboxToValue(checkbox.value);
|
|
307
|
+
} else {
|
|
308
|
+
this.__removeCheckboxFromValue(checkbox.value);
|
|
309
|
+
}
|
|
349
310
|
}
|
|
350
311
|
|
|
351
|
-
/**
|
|
352
|
-
|
|
353
|
-
|
|
312
|
+
/**
|
|
313
|
+
* @param {string | null | undefined} value
|
|
314
|
+
* @private
|
|
315
|
+
*/
|
|
316
|
+
__valueChanged(value) {
|
|
317
|
+
// setting initial value to empty array, skip validation
|
|
318
|
+
if (value.length === 0 && this.__oldValue === undefined) {
|
|
354
319
|
return;
|
|
355
320
|
}
|
|
356
321
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
322
|
+
this.__oldValue = value;
|
|
323
|
+
|
|
324
|
+
this.toggleAttribute('has-value', value.length > 0);
|
|
325
|
+
|
|
326
|
+
this.__checkboxes.forEach((checkbox) => {
|
|
327
|
+
checkbox.checked = value.includes(checkbox.value);
|
|
328
|
+
});
|
|
363
329
|
|
|
364
|
-
|
|
365
|
-
_getErrorMessageAriaHidden(invalid, errorMessage) {
|
|
366
|
-
return (!errorMessage || !invalid).toString();
|
|
330
|
+
this.validate();
|
|
367
331
|
}
|
|
368
332
|
|
|
369
333
|
/**
|
|
334
|
+
* Override method inherited from `FocusMixin`
|
|
335
|
+
* to prevent removing the `focused` attribute
|
|
336
|
+
* when focus moves between checkboxes inside the group.
|
|
337
|
+
*
|
|
338
|
+
* @param {!FocusEvent} event
|
|
370
339
|
* @return {boolean}
|
|
371
340
|
* @protected
|
|
372
341
|
*/
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
return this.contains(activeElement);
|
|
342
|
+
_shouldRemoveFocus(event) {
|
|
343
|
+
return !this.contains(event.relatedTarget);
|
|
376
344
|
}
|
|
377
345
|
|
|
378
346
|
/**
|
|
347
|
+
* Override method inherited from `FocusMixin`
|
|
348
|
+
* to run validation when the group loses focus.
|
|
349
|
+
*
|
|
379
350
|
* @param {boolean} focused
|
|
351
|
+
* @override
|
|
380
352
|
* @protected
|
|
381
353
|
*/
|
|
382
354
|
_setFocused(focused) {
|
|
383
|
-
|
|
384
|
-
this.setAttribute('focused', '');
|
|
385
|
-
} else {
|
|
386
|
-
this.removeAttribute('focused');
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
/** @private */
|
|
391
|
-
_setOrToggleHasHelperAttribute() {
|
|
392
|
-
const slottedNodes = this.shadowRoot.querySelector(`[name="helper"]`).assignedNodes();
|
|
393
|
-
// Only has slotted helper if not a text node
|
|
394
|
-
// Text nodes are added by the helperText prop and not the helper slot
|
|
395
|
-
// The filter is added due to shady DOM triggering this slotchange event on helperText prop change
|
|
396
|
-
this._hasSlottedHelper = slottedNodes.filter((node) => node.nodeType !== 3).length > 0;
|
|
355
|
+
super._setFocused(focused);
|
|
397
356
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
/** @private */
|
|
402
|
-
_getHelperTextAriaHidden(helperText, hasSlottedHelper) {
|
|
403
|
-
return (!(helperText || hasSlottedHelper)).toString();
|
|
357
|
+
if (!focused) {
|
|
358
|
+
this.validate();
|
|
359
|
+
}
|
|
404
360
|
}
|
|
405
361
|
}
|
|
406
362
|
|
|
407
|
-
customElements.define(
|
|
363
|
+
customElements.define(CheckboxGroup.is, CheckboxGroup);
|
|
408
364
|
|
|
409
|
-
export {
|
|
365
|
+
export { CheckboxGroup };
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
|
|
2
2
|
import '@vaadin/vaadin-lumo-styles/color.js';
|
|
3
|
+
import '@vaadin/vaadin-lumo-styles/sizing.js';
|
|
4
|
+
import '@vaadin/vaadin-lumo-styles/spacing.js';
|
|
5
|
+
import '@vaadin/vaadin-lumo-styles/style.js';
|
|
6
|
+
import '@vaadin/vaadin-lumo-styles/typography.js';
|
|
7
|
+
import { helper } from '@vaadin/vaadin-lumo-styles/mixins/helper.js';
|
|
3
8
|
import { requiredField } from '@vaadin/vaadin-lumo-styles/mixins/required-field.js';
|
|
4
9
|
|
|
5
10
|
const checkboxGroup = css`
|
|
@@ -14,7 +19,8 @@ const checkboxGroup = css`
|
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
:host::before {
|
|
17
|
-
height
|
|
22
|
+
/* Effective height of vaadin-checkbox */
|
|
23
|
+
height: var(--lumo-size-s);
|
|
18
24
|
box-sizing: border-box;
|
|
19
25
|
display: inline-flex;
|
|
20
26
|
align-items: center;
|
|
@@ -25,10 +31,6 @@ const checkboxGroup = css`
|
|
|
25
31
|
flex-direction: column;
|
|
26
32
|
}
|
|
27
33
|
|
|
28
|
-
[part='label'] {
|
|
29
|
-
padding-bottom: 0.7em;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
34
|
:host([disabled]) [part='label'] {
|
|
33
35
|
color: var(--lumo-disabled-text-color);
|
|
34
36
|
-webkit-text-fill-color: var(--lumo-disabled-text-color);
|
|
@@ -39,55 +41,10 @@ const checkboxGroup = css`
|
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
:host(:hover:not([disabled]):not([focused])) [part='label'],
|
|
42
|
-
:host(:hover:not([disabled]):not([focused])) [part='helper-text']
|
|
43
|
-
:host(:hover:not([disabled]):not([focused])) [part='helper-text'] ::slotted(*) {
|
|
44
|
+
:host(:hover:not([disabled]):not([focused])) [part='helper-text'] {
|
|
44
45
|
color: var(--lumo-body-text-color);
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
:host([has-helper]) [part='helper-text']::before {
|
|
48
|
-
content: '';
|
|
49
|
-
display: block;
|
|
50
|
-
height: 0.4em;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
[part='helper-text'],
|
|
54
|
-
[part='helper-text'] ::slotted(*) {
|
|
55
|
-
display: block;
|
|
56
|
-
color: var(--lumo-secondary-text-color);
|
|
57
|
-
font-size: var(--lumo-font-size-xs);
|
|
58
|
-
line-height: var(--lumo-line-height-xs);
|
|
59
|
-
margin-left: calc(var(--lumo-border-radius-m) / 4);
|
|
60
|
-
transition: color 0.2s;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/* helper-text position */
|
|
64
|
-
:host([has-helper][theme~='helper-above-field']) [part='helper-text']::before {
|
|
65
|
-
display: none;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
:host([has-helper][theme~='helper-above-field']) [part='helper-text']::after {
|
|
69
|
-
content: '';
|
|
70
|
-
display: block;
|
|
71
|
-
height: 0.4em;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
:host([has-helper][theme~='helper-above-field']) [part='label'] {
|
|
75
|
-
order: 0;
|
|
76
|
-
padding-bottom: 0.4em;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
:host([has-helper][theme~='helper-above-field']) [part='helper-text'] {
|
|
80
|
-
order: 1;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
:host([has-helper][theme~='helper-above-field']) [part='group-field'] {
|
|
84
|
-
order: 2;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
:host([has-helper][theme~='helper-above-field']) [part='error-message'] {
|
|
88
|
-
order: 3;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
48
|
/* Touch device adjustment */
|
|
92
49
|
@media (pointer: coarse) {
|
|
93
50
|
:host(:hover:not([disabled]):not([focused])) [part='label'] {
|
|
@@ -96,6 +53,6 @@ const checkboxGroup = css`
|
|
|
96
53
|
}
|
|
97
54
|
`;
|
|
98
55
|
|
|
99
|
-
registerStyles('vaadin-checkbox-group', [requiredField, checkboxGroup], {
|
|
56
|
+
registerStyles('vaadin-checkbox-group', [requiredField, helper, checkboxGroup], {
|
|
100
57
|
moduleId: 'lumo-checkbox-group'
|
|
101
58
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
|
|
2
2
|
import '@vaadin/vaadin-material-styles/color.js';
|
|
3
|
+
import { helper } from '@vaadin/vaadin-material-styles/mixins/helper.js';
|
|
3
4
|
import { requiredField } from '@vaadin/vaadin-material-styles/mixins/required-field.js';
|
|
4
5
|
|
|
5
6
|
const checkboxGroup = css`
|
|
@@ -25,15 +26,6 @@ const checkboxGroup = css`
|
|
|
25
26
|
padding-top: 24px;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
[part='label']:empty {
|
|
29
|
-
display: none;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
[part='label']:empty::before {
|
|
33
|
-
content: '\\00a0';
|
|
34
|
-
position: absolute;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
29
|
:host([theme~='vertical']) [part='group-field'] {
|
|
38
30
|
display: flex;
|
|
39
31
|
flex-direction: column;
|
|
@@ -47,26 +39,8 @@ const checkboxGroup = css`
|
|
|
47
39
|
:host([focused]:not([invalid])) [part='label'] {
|
|
48
40
|
color: var(--material-primary-text-color);
|
|
49
41
|
}
|
|
50
|
-
|
|
51
|
-
/* According to material theme guidelines, helper text should be hidden when error message is set and input is invalid */
|
|
52
|
-
:host([has-helper][invalid][has-error-message]) [part='helper-text'] {
|
|
53
|
-
display: none;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
:host([has-helper]) [part='helper-text']::before {
|
|
57
|
-
content: '';
|
|
58
|
-
display: block;
|
|
59
|
-
height: 6px;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
[part='helper-text'],
|
|
63
|
-
[part='helper-text'] ::slotted(*) {
|
|
64
|
-
font-size: 0.75rem;
|
|
65
|
-
line-height: 1;
|
|
66
|
-
color: var(--material-secondary-text-color);
|
|
67
|
-
}
|
|
68
42
|
`;
|
|
69
43
|
|
|
70
|
-
registerStyles('vaadin-checkbox-group', [requiredField, checkboxGroup], {
|
|
44
|
+
registerStyles('vaadin-checkbox-group', [requiredField, helper, checkboxGroup], {
|
|
71
45
|
moduleId: 'material-checkbox-group'
|
|
72
46
|
});
|