@vaadin/checkbox-group 24.4.0-alpha17 → 24.4.0-alpha19
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 +10 -9
- package/src/vaadin-checkbox-group-mixin.d.ts +36 -0
- package/src/vaadin-checkbox-group-mixin.js +281 -0
- package/src/vaadin-checkbox-group-styles.d.ts +8 -0
- package/src/vaadin-checkbox-group-styles.js +37 -0
- package/src/vaadin-checkbox-group.d.ts +2 -12
- package/src/vaadin-checkbox-group.js +8 -301
- package/theme/lumo/vaadin-checkbox-group-styles.d.ts +0 -5
- package/theme/lumo/vaadin-checkbox-group.d.ts +0 -3
- package/theme/material/vaadin-checkbox-group-styles.d.ts +0 -1
- package/theme/material/vaadin-checkbox-group.d.ts +0 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/checkbox-group",
|
|
3
|
-
"version": "24.4.0-
|
|
3
|
+
"version": "24.4.0-alpha19",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -35,14 +35,15 @@
|
|
|
35
35
|
"polymer"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
+
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
38
39
|
"@polymer/polymer": "^3.0.0",
|
|
39
|
-
"@vaadin/a11y-base": "24.4.0-
|
|
40
|
-
"@vaadin/checkbox": "24.4.0-
|
|
41
|
-
"@vaadin/component-base": "24.4.0-
|
|
42
|
-
"@vaadin/field-base": "24.4.0-
|
|
43
|
-
"@vaadin/vaadin-lumo-styles": "24.4.0-
|
|
44
|
-
"@vaadin/vaadin-material-styles": "24.4.0-
|
|
45
|
-
"@vaadin/vaadin-themable-mixin": "24.4.0-
|
|
40
|
+
"@vaadin/a11y-base": "24.4.0-alpha19",
|
|
41
|
+
"@vaadin/checkbox": "24.4.0-alpha19",
|
|
42
|
+
"@vaadin/component-base": "24.4.0-alpha19",
|
|
43
|
+
"@vaadin/field-base": "24.4.0-alpha19",
|
|
44
|
+
"@vaadin/vaadin-lumo-styles": "24.4.0-alpha19",
|
|
45
|
+
"@vaadin/vaadin-material-styles": "24.4.0-alpha19",
|
|
46
|
+
"@vaadin/vaadin-themable-mixin": "24.4.0-alpha19"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
48
49
|
"@esm-bundle/chai": "^4.3.4",
|
|
@@ -53,5 +54,5 @@
|
|
|
53
54
|
"web-types.json",
|
|
54
55
|
"web-types.lit.json"
|
|
55
56
|
],
|
|
56
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "5fad5eb53de7da69c1a19776a11ba74ceba27ea0"
|
|
57
58
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2018 - 2024 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import type { Constructor } from '@open-wc/dedupe-mixin';
|
|
7
|
+
import type { DisabledMixinClass } from '@vaadin/a11y-base/src/disabled-mixin.js';
|
|
8
|
+
import type { FocusMixinClass } from '@vaadin/a11y-base/src/focus-mixin.js';
|
|
9
|
+
import type { ControllerMixinClass } from '@vaadin/component-base/src/controller-mixin.js';
|
|
10
|
+
import type { FieldMixinClass } from '@vaadin/field-base/src/field-mixin.js';
|
|
11
|
+
import type { LabelMixinClass } from '@vaadin/field-base/src/label-mixin.js';
|
|
12
|
+
import type { ValidateMixinClass } from '@vaadin/field-base/src/validate-mixin.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A mixin providing common checkbox-group functionality.
|
|
16
|
+
*/
|
|
17
|
+
export declare function CheckboxGroupMixin<T extends Constructor<HTMLElement>>(
|
|
18
|
+
base: T,
|
|
19
|
+
): Constructor<CheckboxGroupMixinClass> &
|
|
20
|
+
Constructor<ControllerMixinClass> &
|
|
21
|
+
Constructor<DisabledMixinClass> &
|
|
22
|
+
Constructor<FieldMixinClass> &
|
|
23
|
+
Constructor<FocusMixinClass> &
|
|
24
|
+
Constructor<LabelMixinClass> &
|
|
25
|
+
Constructor<ValidateMixinClass> &
|
|
26
|
+
T;
|
|
27
|
+
|
|
28
|
+
export declare class CheckboxGroupMixinClass {
|
|
29
|
+
/**
|
|
30
|
+
* An array containing values of the currently checked checkboxes.
|
|
31
|
+
*
|
|
32
|
+
* The array is immutable so toggling checkboxes always results in
|
|
33
|
+
* creating a new array.
|
|
34
|
+
*/
|
|
35
|
+
value: string[];
|
|
36
|
+
}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2018 - 2024 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { DisabledMixin } from '@vaadin/a11y-base/src/disabled-mixin.js';
|
|
7
|
+
import { FocusMixin } from '@vaadin/a11y-base/src/focus-mixin.js';
|
|
8
|
+
import { SlotObserver } from '@vaadin/component-base/src/slot-observer.js';
|
|
9
|
+
import { TooltipController } from '@vaadin/component-base/src/tooltip-controller.js';
|
|
10
|
+
import { FieldMixin } from '@vaadin/field-base/src/field-mixin.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A mixin providing common checkbox-group functionality.
|
|
14
|
+
*
|
|
15
|
+
* @polymerMixin
|
|
16
|
+
* @mixes DisabledMixin
|
|
17
|
+
* @mixes FieldMixin
|
|
18
|
+
* @mixes FocusMixin
|
|
19
|
+
* @mixes KeyboardMixin
|
|
20
|
+
*/
|
|
21
|
+
export const CheckboxGroupMixin = (superclass) =>
|
|
22
|
+
class CheckboxGroupMixinClass extends FieldMixin(FocusMixin(DisabledMixin(superclass))) {
|
|
23
|
+
static get properties() {
|
|
24
|
+
return {
|
|
25
|
+
/**
|
|
26
|
+
* An array containing values of the currently checked checkboxes.
|
|
27
|
+
*
|
|
28
|
+
* The array is immutable so toggling checkboxes always results in
|
|
29
|
+
* creating a new array.
|
|
30
|
+
*
|
|
31
|
+
* @type {!Array<!string>}
|
|
32
|
+
*/
|
|
33
|
+
value: {
|
|
34
|
+
type: Array,
|
|
35
|
+
value: () => [],
|
|
36
|
+
notify: true,
|
|
37
|
+
observer: '__valueChanged',
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
constructor() {
|
|
43
|
+
super();
|
|
44
|
+
|
|
45
|
+
this.__registerCheckbox = this.__registerCheckbox.bind(this);
|
|
46
|
+
this.__unregisterCheckbox = this.__unregisterCheckbox.bind(this);
|
|
47
|
+
this.__onCheckboxCheckedChanged = this.__onCheckboxCheckedChanged.bind(this);
|
|
48
|
+
|
|
49
|
+
this._tooltipController = new TooltipController(this);
|
|
50
|
+
this._tooltipController.addEventListener('tooltip-changed', (event) => {
|
|
51
|
+
const tooltip = event.detail.node;
|
|
52
|
+
if (tooltip && tooltip.isConnected) {
|
|
53
|
+
// Tooltip element has been added to the DOM
|
|
54
|
+
const inputs = this.__checkboxes.map((checkbox) => checkbox.inputElement);
|
|
55
|
+
this._tooltipController.setAriaTarget(inputs);
|
|
56
|
+
} else {
|
|
57
|
+
// Tooltip element is no longer connected
|
|
58
|
+
this._tooltipController.setAriaTarget([]);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* A collection of the checkboxes.
|
|
65
|
+
*
|
|
66
|
+
* @return {!Array<!Checkbox>}
|
|
67
|
+
* @private
|
|
68
|
+
*/
|
|
69
|
+
get __checkboxes() {
|
|
70
|
+
return this.__filterCheckboxes([...this.children]);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** @protected */
|
|
74
|
+
ready() {
|
|
75
|
+
super.ready();
|
|
76
|
+
|
|
77
|
+
this.ariaTarget = this;
|
|
78
|
+
|
|
79
|
+
// See https://github.com/vaadin/vaadin-web-components/issues/94
|
|
80
|
+
this.setAttribute('role', 'group');
|
|
81
|
+
|
|
82
|
+
const slot = this.shadowRoot.querySelector('slot:not([name])');
|
|
83
|
+
this._observer = new SlotObserver(slot, ({ addedNodes, removedNodes }) => {
|
|
84
|
+
const addedCheckboxes = this.__filterCheckboxes(addedNodes);
|
|
85
|
+
const removedCheckboxes = this.__filterCheckboxes(removedNodes);
|
|
86
|
+
|
|
87
|
+
addedCheckboxes.forEach(this.__registerCheckbox);
|
|
88
|
+
removedCheckboxes.forEach(this.__unregisterCheckbox);
|
|
89
|
+
|
|
90
|
+
const inputs = this.__checkboxes.map((checkbox) => checkbox.inputElement);
|
|
91
|
+
this._tooltipController.setAriaTarget(inputs);
|
|
92
|
+
|
|
93
|
+
this.__warnOfCheckboxesWithoutValue(addedCheckboxes);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
this.addController(this._tooltipController);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Override method inherited from `ValidateMixin`
|
|
101
|
+
* to validate the value array.
|
|
102
|
+
*
|
|
103
|
+
* @override
|
|
104
|
+
* @return {boolean}
|
|
105
|
+
*/
|
|
106
|
+
checkValidity() {
|
|
107
|
+
return !this.required || this.value.length > 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @param {!Array<!Node>} nodes
|
|
112
|
+
* @return {!Array<!Checkbox>}
|
|
113
|
+
* @private
|
|
114
|
+
*/
|
|
115
|
+
__filterCheckboxes(nodes) {
|
|
116
|
+
return nodes.filter((node) => node.nodeType === Node.ELEMENT_NODE && node.localName === 'vaadin-checkbox');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @param {!Array<!Checkbox>} checkboxes
|
|
121
|
+
* @private
|
|
122
|
+
*/
|
|
123
|
+
__warnOfCheckboxesWithoutValue(checkboxes) {
|
|
124
|
+
const hasCheckboxesWithoutValue = checkboxes.some((checkbox) => {
|
|
125
|
+
const { value } = checkbox;
|
|
126
|
+
|
|
127
|
+
return !checkbox.hasAttribute('value') && (!value || value === 'on');
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
if (hasCheckboxesWithoutValue) {
|
|
131
|
+
console.warn('Please provide the value attribute to all the checkboxes inside the checkbox group.');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Registers the checkbox after adding it to the group.
|
|
137
|
+
*
|
|
138
|
+
* @param {!Checkbox} checkbox
|
|
139
|
+
* @private
|
|
140
|
+
*/
|
|
141
|
+
__registerCheckbox(checkbox) {
|
|
142
|
+
checkbox.addEventListener('checked-changed', this.__onCheckboxCheckedChanged);
|
|
143
|
+
|
|
144
|
+
if (this.disabled) {
|
|
145
|
+
checkbox.disabled = true;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (checkbox.checked) {
|
|
149
|
+
this.__addCheckboxToValue(checkbox.value);
|
|
150
|
+
} else if (this.value.includes(checkbox.value)) {
|
|
151
|
+
checkbox.checked = true;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Unregisters the checkbox before removing it from the group.
|
|
157
|
+
*
|
|
158
|
+
* @param {!Checkbox} checkbox
|
|
159
|
+
* @private
|
|
160
|
+
*/
|
|
161
|
+
__unregisterCheckbox(checkbox) {
|
|
162
|
+
checkbox.removeEventListener('checked-changed', this.__onCheckboxCheckedChanged);
|
|
163
|
+
|
|
164
|
+
if (checkbox.checked) {
|
|
165
|
+
this.__removeCheckboxFromValue(checkbox.value);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Override method inherited from `DisabledMixin`
|
|
171
|
+
* to propagate the `disabled` property to the checkboxes.
|
|
172
|
+
*
|
|
173
|
+
* @param {boolean} newValue
|
|
174
|
+
* @param {boolean} oldValue
|
|
175
|
+
* @override
|
|
176
|
+
* @protected
|
|
177
|
+
*/
|
|
178
|
+
_disabledChanged(newValue, oldValue) {
|
|
179
|
+
super._disabledChanged(newValue, oldValue);
|
|
180
|
+
|
|
181
|
+
// Prevent updating the `disabled` property for the checkboxes at initialization.
|
|
182
|
+
// Otherwise, the checkboxes may end up enabled regardless the `disabled` attribute
|
|
183
|
+
// intentionally added by the user on some of them.
|
|
184
|
+
if (!newValue && oldValue === undefined) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (oldValue !== newValue) {
|
|
189
|
+
this.__checkboxes.forEach((checkbox) => {
|
|
190
|
+
checkbox.disabled = newValue;
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* @param {string} value
|
|
197
|
+
* @private
|
|
198
|
+
*/
|
|
199
|
+
__addCheckboxToValue(value) {
|
|
200
|
+
if (!this.value.includes(value)) {
|
|
201
|
+
this.value = [...this.value, value];
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* @param {string} value
|
|
207
|
+
* @private
|
|
208
|
+
*/
|
|
209
|
+
__removeCheckboxFromValue(value) {
|
|
210
|
+
if (this.value.includes(value)) {
|
|
211
|
+
this.value = this.value.filter((v) => v !== value);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* @param {!CustomEvent} event
|
|
217
|
+
* @private
|
|
218
|
+
*/
|
|
219
|
+
__onCheckboxCheckedChanged(event) {
|
|
220
|
+
const checkbox = event.target;
|
|
221
|
+
|
|
222
|
+
if (checkbox.checked) {
|
|
223
|
+
this.__addCheckboxToValue(checkbox.value);
|
|
224
|
+
} else {
|
|
225
|
+
this.__removeCheckboxFromValue(checkbox.value);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* @param {string | null | undefined} value
|
|
231
|
+
* @param {string | null | undefined} oldValue
|
|
232
|
+
* @private
|
|
233
|
+
*/
|
|
234
|
+
__valueChanged(value, oldValue) {
|
|
235
|
+
// Setting initial value to empty array, skip validation
|
|
236
|
+
if (value.length === 0 && oldValue === undefined) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
this.toggleAttribute('has-value', value.length > 0);
|
|
241
|
+
|
|
242
|
+
this.__checkboxes.forEach((checkbox) => {
|
|
243
|
+
checkbox.checked = value.includes(checkbox.value);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
if (oldValue !== undefined) {
|
|
247
|
+
this.validate();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Override method inherited from `FocusMixin`
|
|
253
|
+
* to prevent removing the `focused` attribute
|
|
254
|
+
* when focus moves between checkboxes inside the group.
|
|
255
|
+
*
|
|
256
|
+
* @param {!FocusEvent} event
|
|
257
|
+
* @return {boolean}
|
|
258
|
+
* @protected
|
|
259
|
+
*/
|
|
260
|
+
_shouldRemoveFocus(event) {
|
|
261
|
+
return !this.contains(event.relatedTarget);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Override method inherited from `FocusMixin`
|
|
266
|
+
* to run validation when the group loses focus.
|
|
267
|
+
*
|
|
268
|
+
* @param {boolean} focused
|
|
269
|
+
* @override
|
|
270
|
+
* @protected
|
|
271
|
+
*/
|
|
272
|
+
_setFocused(focused) {
|
|
273
|
+
super._setFocused(focused);
|
|
274
|
+
|
|
275
|
+
// Do not validate when focusout is caused by document
|
|
276
|
+
// losing focus, which happens on browser tab switch.
|
|
277
|
+
if (!focused && document.hasFocus()) {
|
|
278
|
+
this.validate();
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2018 - 2024 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { css } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
7
|
+
|
|
8
|
+
export const checkboxGroupStyles = css`
|
|
9
|
+
:host {
|
|
10
|
+
display: inline-flex;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
:host::before {
|
|
14
|
+
content: '\\2003';
|
|
15
|
+
width: 0;
|
|
16
|
+
display: inline-block;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
:host([hidden]) {
|
|
20
|
+
display: none !important;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.vaadin-group-field-container {
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: column;
|
|
26
|
+
width: 100%;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
[part='group-field'] {
|
|
30
|
+
display: flex;
|
|
31
|
+
flex-wrap: wrap;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
:host(:not([has-label])) [part='label'] {
|
|
35
|
+
display: none;
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
@@ -3,11 +3,9 @@
|
|
|
3
3
|
* Copyright (c) 2018 - 2024 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
-
import { DisabledMixin } from '@vaadin/a11y-base/src/disabled-mixin.js';
|
|
7
|
-
import { FocusMixin } from '@vaadin/a11y-base/src/focus-mixin.js';
|
|
8
6
|
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
|
|
9
|
-
import { FieldMixin } from '@vaadin/field-base/src/field-mixin.js';
|
|
10
7
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
8
|
+
import { CheckboxGroupMixin } from './vaadin-checkbox-group-mixin.js';
|
|
11
9
|
|
|
12
10
|
/**
|
|
13
11
|
* Fired when the `invalid` property changes.
|
|
@@ -76,15 +74,7 @@ export interface CheckboxGroupEventMap extends HTMLElementEventMap, CheckboxGrou
|
|
|
76
74
|
* @fires {CustomEvent} value-changed - Fired when the `value` property changes.
|
|
77
75
|
* @fires {CustomEvent} validated - Fired whenever the field is validated.
|
|
78
76
|
*/
|
|
79
|
-
declare class CheckboxGroup extends
|
|
80
|
-
/**
|
|
81
|
-
* An array containing values of the currently checked checkboxes.
|
|
82
|
-
*
|
|
83
|
-
* The array is immutable so toggling checkboxes always results in
|
|
84
|
-
* creating a new array.
|
|
85
|
-
*/
|
|
86
|
-
value: string[];
|
|
87
|
-
|
|
77
|
+
declare class CheckboxGroup extends CheckboxGroupMixin(ElementMixin(ThemableMixin(HTMLElement))) {
|
|
88
78
|
addEventListener<K extends keyof CheckboxGroupEventMap>(
|
|
89
79
|
type: K,
|
|
90
80
|
listener: (this: CheckboxGroup, ev: CheckboxGroupEventMap[K]) => void,
|
|
@@ -3,16 +3,15 @@
|
|
|
3
3
|
* Copyright (c) 2018 - 2024 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
+
import '@vaadin/checkbox/src/vaadin-checkbox.js';
|
|
6
7
|
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
7
|
-
import { DisabledMixin } from '@vaadin/a11y-base/src/disabled-mixin.js';
|
|
8
|
-
import { FocusMixin } from '@vaadin/a11y-base/src/focus-mixin.js';
|
|
9
|
-
import { Checkbox } from '@vaadin/checkbox/src/vaadin-checkbox.js';
|
|
10
8
|
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
11
9
|
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
|
|
10
|
+
import { registerStyles, ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
11
|
+
import { CheckboxGroupMixin } from './vaadin-checkbox-group-mixin.js';
|
|
12
|
+
import { checkboxGroupStyles } from './vaadin-checkbox-group-styles.js';
|
|
13
|
+
|
|
14
|
+
registerStyles('vaadin-checkbox-group', checkboxGroupStyles, { moduleId: 'vaadin-checkbox-group-styles' });
|
|
16
15
|
|
|
17
16
|
/**
|
|
18
17
|
* `<vaadin-checkbox-group>` is a web component that allows the user to choose several items from a group of binary choices.
|
|
@@ -59,49 +58,16 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
|
|
|
59
58
|
* @customElement
|
|
60
59
|
* @extends HTMLElement
|
|
61
60
|
* @mixes ThemableMixin
|
|
62
|
-
* @mixes DisabledMixin
|
|
63
61
|
* @mixes ElementMixin
|
|
64
|
-
* @mixes
|
|
65
|
-
* @mixes FieldMixin
|
|
62
|
+
* @mixes CheckboxGroupMixin
|
|
66
63
|
*/
|
|
67
|
-
class CheckboxGroup extends
|
|
64
|
+
class CheckboxGroup extends CheckboxGroupMixin(ElementMixin(ThemableMixin(PolymerElement))) {
|
|
68
65
|
static get is() {
|
|
69
66
|
return 'vaadin-checkbox-group';
|
|
70
67
|
}
|
|
71
68
|
|
|
72
69
|
static get template() {
|
|
73
70
|
return html`
|
|
74
|
-
<style>
|
|
75
|
-
:host {
|
|
76
|
-
display: inline-flex;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
:host::before {
|
|
80
|
-
content: '\\2003';
|
|
81
|
-
width: 0;
|
|
82
|
-
display: inline-block;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
:host([hidden]) {
|
|
86
|
-
display: none !important;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
.vaadin-group-field-container {
|
|
90
|
-
display: flex;
|
|
91
|
-
flex-direction: column;
|
|
92
|
-
width: 100%;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
[part='group-field'] {
|
|
96
|
-
display: flex;
|
|
97
|
-
flex-wrap: wrap;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
:host(:not([has-label])) [part='label'] {
|
|
101
|
-
display: none;
|
|
102
|
-
}
|
|
103
|
-
</style>
|
|
104
|
-
|
|
105
71
|
<div class="vaadin-group-field-container">
|
|
106
72
|
<div part="label">
|
|
107
73
|
<slot name="label"></slot>
|
|
@@ -124,265 +90,6 @@ class CheckboxGroup extends FieldMixin(FocusMixin(DisabledMixin(ElementMixin(The
|
|
|
124
90
|
<slot name="tooltip"></slot>
|
|
125
91
|
`;
|
|
126
92
|
}
|
|
127
|
-
|
|
128
|
-
static get properties() {
|
|
129
|
-
return {
|
|
130
|
-
/**
|
|
131
|
-
* An array containing values of the currently checked checkboxes.
|
|
132
|
-
*
|
|
133
|
-
* The array is immutable so toggling checkboxes always results in
|
|
134
|
-
* creating a new array.
|
|
135
|
-
*
|
|
136
|
-
* @type {!Array<!string>}
|
|
137
|
-
*/
|
|
138
|
-
value: {
|
|
139
|
-
type: Array,
|
|
140
|
-
value: () => [],
|
|
141
|
-
notify: true,
|
|
142
|
-
observer: '__valueChanged',
|
|
143
|
-
},
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
constructor() {
|
|
148
|
-
super();
|
|
149
|
-
|
|
150
|
-
this.__registerCheckbox = this.__registerCheckbox.bind(this);
|
|
151
|
-
this.__unregisterCheckbox = this.__unregisterCheckbox.bind(this);
|
|
152
|
-
this.__onCheckboxCheckedChanged = this.__onCheckboxCheckedChanged.bind(this);
|
|
153
|
-
|
|
154
|
-
this._tooltipController = new TooltipController(this);
|
|
155
|
-
this._tooltipController.addEventListener('tooltip-changed', (event) => {
|
|
156
|
-
const tooltip = event.detail.node;
|
|
157
|
-
if (tooltip && tooltip.isConnected) {
|
|
158
|
-
// Tooltip element has been added to the DOM
|
|
159
|
-
const inputs = this.__checkboxes.map((checkbox) => checkbox.inputElement);
|
|
160
|
-
this._tooltipController.setAriaTarget(inputs);
|
|
161
|
-
} else {
|
|
162
|
-
// Tooltip element is no longer connected
|
|
163
|
-
this._tooltipController.setAriaTarget([]);
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* A collection of the checkboxes.
|
|
170
|
-
*
|
|
171
|
-
* @return {!Array<!Checkbox>}
|
|
172
|
-
* @private
|
|
173
|
-
*/
|
|
174
|
-
get __checkboxes() {
|
|
175
|
-
return this.__filterCheckboxes([...this.children]);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/** @protected */
|
|
179
|
-
ready() {
|
|
180
|
-
super.ready();
|
|
181
|
-
|
|
182
|
-
this.ariaTarget = this;
|
|
183
|
-
|
|
184
|
-
// See https://github.com/vaadin/vaadin-web-components/issues/94
|
|
185
|
-
this.setAttribute('role', 'group');
|
|
186
|
-
|
|
187
|
-
const slot = this.shadowRoot.querySelector('slot:not([name])');
|
|
188
|
-
this._observer = new SlotObserver(slot, ({ addedNodes, removedNodes }) => {
|
|
189
|
-
const addedCheckboxes = this.__filterCheckboxes(addedNodes);
|
|
190
|
-
const removedCheckboxes = this.__filterCheckboxes(removedNodes);
|
|
191
|
-
|
|
192
|
-
addedCheckboxes.forEach(this.__registerCheckbox);
|
|
193
|
-
removedCheckboxes.forEach(this.__unregisterCheckbox);
|
|
194
|
-
|
|
195
|
-
const inputs = this.__checkboxes.map((checkbox) => checkbox.inputElement);
|
|
196
|
-
this._tooltipController.setAriaTarget(inputs);
|
|
197
|
-
|
|
198
|
-
this.__warnOfCheckboxesWithoutValue(addedCheckboxes);
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
this.addController(this._tooltipController);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Override method inherited from `ValidateMixin`
|
|
206
|
-
* to validate the value array.
|
|
207
|
-
*
|
|
208
|
-
* @override
|
|
209
|
-
* @return {boolean}
|
|
210
|
-
*/
|
|
211
|
-
checkValidity() {
|
|
212
|
-
return !this.required || this.value.length > 0;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* @param {!Array<!Node>} nodes
|
|
217
|
-
* @return {!Array<!Checkbox>}
|
|
218
|
-
* @private
|
|
219
|
-
*/
|
|
220
|
-
__filterCheckboxes(nodes) {
|
|
221
|
-
return nodes.filter((child) => child instanceof Checkbox);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* @param {!Array<!Checkbox>} checkboxes
|
|
226
|
-
* @private
|
|
227
|
-
*/
|
|
228
|
-
__warnOfCheckboxesWithoutValue(checkboxes) {
|
|
229
|
-
const hasCheckboxesWithoutValue = checkboxes.some((checkbox) => {
|
|
230
|
-
const { value } = checkbox;
|
|
231
|
-
|
|
232
|
-
return !checkbox.hasAttribute('value') && (!value || value === 'on');
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
if (hasCheckboxesWithoutValue) {
|
|
236
|
-
console.warn('Please provide the value attribute to all the checkboxes inside the checkbox group.');
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Registers the checkbox after adding it to the group.
|
|
242
|
-
*
|
|
243
|
-
* @param {!Checkbox} checkbox
|
|
244
|
-
* @private
|
|
245
|
-
*/
|
|
246
|
-
__registerCheckbox(checkbox) {
|
|
247
|
-
checkbox.addEventListener('checked-changed', this.__onCheckboxCheckedChanged);
|
|
248
|
-
|
|
249
|
-
if (this.disabled) {
|
|
250
|
-
checkbox.disabled = true;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
if (checkbox.checked) {
|
|
254
|
-
this.__addCheckboxToValue(checkbox.value);
|
|
255
|
-
} else if (this.value.includes(checkbox.value)) {
|
|
256
|
-
checkbox.checked = true;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Unregisters the checkbox before removing it from the group.
|
|
262
|
-
*
|
|
263
|
-
* @param {!Checkbox} checkbox
|
|
264
|
-
* @private
|
|
265
|
-
*/
|
|
266
|
-
__unregisterCheckbox(checkbox) {
|
|
267
|
-
checkbox.removeEventListener('checked-changed', this.__onCheckboxCheckedChanged);
|
|
268
|
-
|
|
269
|
-
if (checkbox.checked) {
|
|
270
|
-
this.__removeCheckboxFromValue(checkbox.value);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Override method inherited from `DisabledMixin`
|
|
276
|
-
* to propagate the `disabled` property to the checkboxes.
|
|
277
|
-
*
|
|
278
|
-
* @param {boolean} newValue
|
|
279
|
-
* @param {boolean} oldValue
|
|
280
|
-
* @override
|
|
281
|
-
* @protected
|
|
282
|
-
*/
|
|
283
|
-
_disabledChanged(newValue, oldValue) {
|
|
284
|
-
super._disabledChanged(newValue, oldValue);
|
|
285
|
-
|
|
286
|
-
// Prevent updating the `disabled` property for the checkboxes at initialization.
|
|
287
|
-
// Otherwise, the checkboxes may end up enabled regardless the `disabled` attribute
|
|
288
|
-
// intentionally added by the user on some of them.
|
|
289
|
-
if (!newValue && oldValue === undefined) {
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
if (oldValue !== newValue) {
|
|
294
|
-
this.__checkboxes.forEach((checkbox) => {
|
|
295
|
-
checkbox.disabled = newValue;
|
|
296
|
-
});
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* @param {string} value
|
|
302
|
-
* @private
|
|
303
|
-
*/
|
|
304
|
-
__addCheckboxToValue(value) {
|
|
305
|
-
if (!this.value.includes(value)) {
|
|
306
|
-
this.value = [...this.value, value];
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* @param {string} value
|
|
312
|
-
* @private
|
|
313
|
-
*/
|
|
314
|
-
__removeCheckboxFromValue(value) {
|
|
315
|
-
if (this.value.includes(value)) {
|
|
316
|
-
this.value = this.value.filter((v) => v !== value);
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
/**
|
|
321
|
-
* @param {!CustomEvent} event
|
|
322
|
-
* @private
|
|
323
|
-
*/
|
|
324
|
-
__onCheckboxCheckedChanged(event) {
|
|
325
|
-
const checkbox = event.target;
|
|
326
|
-
|
|
327
|
-
if (checkbox.checked) {
|
|
328
|
-
this.__addCheckboxToValue(checkbox.value);
|
|
329
|
-
} else {
|
|
330
|
-
this.__removeCheckboxFromValue(checkbox.value);
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* @param {string | null | undefined} value
|
|
336
|
-
* @param {string | null | undefined} oldValue
|
|
337
|
-
* @private
|
|
338
|
-
*/
|
|
339
|
-
__valueChanged(value, oldValue) {
|
|
340
|
-
// Setting initial value to empty array, skip validation
|
|
341
|
-
if (value.length === 0 && oldValue === undefined) {
|
|
342
|
-
return;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
this.toggleAttribute('has-value', value.length > 0);
|
|
346
|
-
|
|
347
|
-
this.__checkboxes.forEach((checkbox) => {
|
|
348
|
-
checkbox.checked = value.includes(checkbox.value);
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
if (oldValue !== undefined) {
|
|
352
|
-
this.validate();
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
/**
|
|
357
|
-
* Override method inherited from `FocusMixin`
|
|
358
|
-
* to prevent removing the `focused` attribute
|
|
359
|
-
* when focus moves between checkboxes inside the group.
|
|
360
|
-
*
|
|
361
|
-
* @param {!FocusEvent} event
|
|
362
|
-
* @return {boolean}
|
|
363
|
-
* @protected
|
|
364
|
-
*/
|
|
365
|
-
_shouldRemoveFocus(event) {
|
|
366
|
-
return !this.contains(event.relatedTarget);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* Override method inherited from `FocusMixin`
|
|
371
|
-
* to run validation when the group loses focus.
|
|
372
|
-
*
|
|
373
|
-
* @param {boolean} focused
|
|
374
|
-
* @override
|
|
375
|
-
* @protected
|
|
376
|
-
*/
|
|
377
|
-
_setFocused(focused) {
|
|
378
|
-
super._setFocused(focused);
|
|
379
|
-
|
|
380
|
-
// Do not validate when focusout is caused by document
|
|
381
|
-
// losing focus, which happens on browser tab switch.
|
|
382
|
-
if (!focused && document.hasFocus()) {
|
|
383
|
-
this.validate();
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
93
|
}
|
|
387
94
|
|
|
388
95
|
defineCustomElement(CheckboxGroup);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import '@vaadin/vaadin-material-styles/color.js';
|