@everymatrix/general-input 1.10.2 → 1.15.0
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/dist/cjs/checkbox-group-input_10.cjs.entry.js +35539 -0
- package/dist/cjs/general-input.cjs.entry.js +34 -13
- package/dist/cjs/general-input.cjs.js +2 -2
- package/dist/cjs/{index-64a5cb7f.js → index-132a0774.js} +119 -6
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/locale.utils-7665b010.js +71 -0
- package/dist/cjs/toggle-checkbox-input.cjs.entry.js +85 -0
- package/dist/cjs/tooltipIcon-092a795f.js +5 -0
- package/dist/collection/collection-manifest.json +3 -1
- package/dist/collection/components/checkbox-group-input/checkbox-group-input.css +62 -0
- package/dist/collection/components/checkbox-group-input/checkbox-group-input.js +366 -0
- package/dist/collection/components/checkbox-input/checkbox-input.css +47 -1
- package/dist/collection/components/checkbox-input/checkbox-input.js +143 -16
- package/dist/collection/components/date-input/date-input.css +64 -30
- package/dist/collection/components/date-input/date-input.js +194 -13
- package/dist/collection/components/email-input/email-input.css +63 -28
- package/dist/collection/components/email-input/email-input.js +197 -21
- package/dist/collection/components/general-input/general-input.js +163 -21
- package/dist/collection/components/number-input/number-input.css +65 -30
- package/dist/collection/components/number-input/number-input.js +174 -19
- package/dist/collection/components/password-input/password-input.css +120 -29
- package/dist/collection/components/password-input/password-input.js +341 -25
- package/dist/collection/components/radio-input/radio-input.css +22 -1
- package/dist/collection/components/radio-input/radio-input.js +89 -10
- package/dist/collection/components/select-input/select-input.css +75 -22
- package/dist/collection/components/select-input/select-input.js +180 -37
- package/dist/collection/components/tel-input/tel-input.css +91 -33
- package/dist/collection/components/tel-input/tel-input.js +202 -24
- package/dist/collection/components/text-input/text-input.css +63 -28
- package/dist/collection/components/text-input/text-input.js +208 -39
- package/dist/collection/components/toggle-checkbox-input/toggle-checkbox-input.css +76 -0
- package/dist/collection/components/toggle-checkbox-input/toggle-checkbox-input.js +324 -0
- package/dist/collection/utils/locale.utils.js +52 -13
- package/dist/collection/utils/tooltipIcon.svg +5 -0
- package/dist/components/active-mixin.js +975 -0
- package/dist/components/checkbox-group-input.d.ts +11 -0
- package/dist/components/checkbox-group-input.js +6 -0
- package/dist/components/checkbox-group-input2.js +1125 -0
- package/dist/components/checkbox-input2.js +62 -12
- package/dist/components/date-input2.js +10247 -15
- package/dist/components/email-input2.js +98 -21
- package/dist/components/field-mixin.js +12712 -0
- package/dist/components/general-input.js +1 -118
- package/dist/components/general-input2.js +331 -0
- package/dist/components/input-field-shared-styles.js +1114 -0
- package/dist/components/number-input2.js +92 -16
- package/dist/components/password-input2.js +924 -24
- package/dist/components/pattern-mixin.js +85 -0
- package/dist/components/radio-input2.js +45 -11
- package/dist/components/select-input2.js +87 -27
- package/dist/components/tel-input2.js +122 -22
- package/dist/components/text-input2.js +120 -34
- package/dist/components/toggle-checkbox-input.d.ts +11 -0
- package/dist/components/toggle-checkbox-input.js +6 -0
- package/dist/components/tooltipIcon.js +70 -0
- package/dist/components/vaadin-button.js +461 -0
- package/dist/components/vaadin-combo-box.js +4329 -0
- package/dist/components/virtual-keyboard-controller.js +2658 -0
- package/dist/esm/checkbox-group-input_10.entry.js +35526 -0
- package/dist/esm/general-input.entry.js +34 -13
- package/dist/esm/general-input.js +2 -2
- package/dist/esm/{index-df80f936.js → index-db76d5b5.js} +118 -7
- package/dist/esm/loader.js +2 -2
- package/dist/esm/locale.utils-95ea2605.js +68 -0
- package/dist/esm/toggle-checkbox-input.entry.js +81 -0
- package/dist/esm/tooltipIcon-99c1c7b7.js +3 -0
- package/dist/general-input/general-input.esm.js +1 -1
- package/dist/general-input/p-0966f523.entry.js +3581 -0
- package/dist/general-input/p-916a1319.entry.js +1 -0
- package/dist/general-input/p-b408093e.js +1 -0
- package/dist/general-input/p-c2d4d6ac.entry.js +1 -0
- package/dist/general-input/p-f4f4ccda.js +1 -0
- package/dist/general-input/p-f6132f1d.js +1 -0
- package/dist/types/components/checkbox-group-input/checkbox-group-input.d.ts +74 -0
- package/dist/types/components/checkbox-input/checkbox-input.d.ts +28 -2
- package/dist/types/components/date-input/date-input.d.ts +43 -1
- package/dist/types/components/email-input/email-input.d.ts +37 -3
- package/dist/types/components/general-input/general-input.d.ts +30 -0
- package/dist/types/components/number-input/number-input.d.ts +34 -3
- package/dist/types/components/password-input/password-input.d.ts +56 -7
- package/dist/types/components/radio-input/radio-input.d.ts +17 -1
- package/dist/types/components/select-input/select-input.d.ts +36 -3
- package/dist/types/components/tel-input/tel-input.d.ts +40 -5
- package/dist/types/components/text-input/text-input.d.ts +84 -0
- package/dist/types/components/toggle-checkbox-input/toggle-checkbox-input.d.ts +67 -0
- package/dist/types/components.d.ts +568 -9
- package/dist/types/utils/locale.utils.d.ts +9 -0
- package/dist/types/utils/types.d.ts +41 -9
- package/package.json +8 -1
- package/dist/cjs/checkbox-input_9.cjs.entry.js +0 -623
- package/dist/components/locale.utils.js +0 -29
- package/dist/esm/checkbox-input_9.entry.js +0 -611
- package/dist/general-input/p-1703fce3.entry.js +0 -1
- package/dist/general-input/p-d9f7fa2e.js +0 -1
- package/dist/general-input/p-dea0a4ac.entry.js +0 -1
- /package/dist/types/Users/{user/workspace/everymatrix → adrian.pripon/Documents/Work}/widgets-stencil/packages/general-input/.stencil/packages/general-input/stencil.config.d.ts +0 -0
|
@@ -0,0 +1,1125 @@
|
|
|
1
|
+
import { proxyCustomElement, HTMLElement, createEvent, h } from '@stencil/core/internal/client';
|
|
2
|
+
import { t as translate, a as tooltipIconSvg } from './tooltipIcon.js';
|
|
3
|
+
import { r as registerStyles, i, d as dedupingMixin, D as DelegateStateMixin, a as DisabledMixin, I as InputMixin, b as isElementFocused, L as LabelMixin, c as DelegateFocusMixin, E as ElementMixin, T as ThemableMixin, C as ControllerMixin, P as PolymerElement, h as html, e as InputController, f as LabelledInputController, g as TooltipController, j as requiredField, k as helper, F as FieldMixin, l as FocusMixin, m as FlattenedNodesObserver } from './field-mixin.js';
|
|
4
|
+
import { A as ActiveMixin } from './active-mixin.js';
|
|
5
|
+
|
|
6
|
+
registerStyles(
|
|
7
|
+
'vaadin-checkbox',
|
|
8
|
+
i`
|
|
9
|
+
:host {
|
|
10
|
+
color: var(--lumo-body-text-color);
|
|
11
|
+
font-size: var(--lumo-font-size-m);
|
|
12
|
+
font-family: var(--lumo-font-family);
|
|
13
|
+
line-height: var(--lumo-line-height-s);
|
|
14
|
+
-webkit-font-smoothing: antialiased;
|
|
15
|
+
-moz-osx-font-smoothing: grayscale;
|
|
16
|
+
-webkit-tap-highlight-color: transparent;
|
|
17
|
+
-webkit-user-select: none;
|
|
18
|
+
-moz-user-select: none;
|
|
19
|
+
user-select: none;
|
|
20
|
+
cursor: default;
|
|
21
|
+
outline: none;
|
|
22
|
+
--_checkbox-size: var(--vaadin-checkbox-size, calc(var(--lumo-size-m) / 2));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
:host([has-label]) ::slotted(label) {
|
|
26
|
+
padding-block: var(--lumo-space-xs);
|
|
27
|
+
padding-inline: var(--lumo-space-xs) var(--lumo-space-s);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
[part='checkbox'] {
|
|
31
|
+
width: var(--_checkbox-size);
|
|
32
|
+
height: var(--_checkbox-size);
|
|
33
|
+
margin: var(--lumo-space-xs);
|
|
34
|
+
position: relative;
|
|
35
|
+
border-radius: var(--lumo-border-radius-s);
|
|
36
|
+
background-color: var(--lumo-contrast-20pct);
|
|
37
|
+
transition: transform 0.2s cubic-bezier(0.12, 0.32, 0.54, 2), background-color 0.15s;
|
|
38
|
+
cursor: var(--lumo-clickable-cursor);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
:host([indeterminate]) [part='checkbox'],
|
|
42
|
+
:host([checked]) [part='checkbox'] {
|
|
43
|
+
background-color: var(--lumo-primary-color);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Checkmark */
|
|
47
|
+
[part='checkbox']::after {
|
|
48
|
+
pointer-events: none;
|
|
49
|
+
font-family: 'lumo-icons';
|
|
50
|
+
content: var(--lumo-icons-checkmark);
|
|
51
|
+
color: var(--lumo-primary-contrast-color);
|
|
52
|
+
font-size: calc(var(--_checkbox-size) + 2px);
|
|
53
|
+
line-height: 1;
|
|
54
|
+
position: absolute;
|
|
55
|
+
top: -1px;
|
|
56
|
+
left: -1px;
|
|
57
|
+
contain: content;
|
|
58
|
+
opacity: 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
:host([checked]) [part='checkbox']::after {
|
|
62
|
+
opacity: 1;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* Indeterminate checkmark */
|
|
66
|
+
:host([indeterminate]) [part='checkbox']::after {
|
|
67
|
+
content: '';
|
|
68
|
+
opacity: 1;
|
|
69
|
+
top: 45%;
|
|
70
|
+
height: 10%;
|
|
71
|
+
left: 22%;
|
|
72
|
+
right: 22%;
|
|
73
|
+
width: auto;
|
|
74
|
+
border: 0;
|
|
75
|
+
background-color: var(--lumo-primary-contrast-color);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* Focus ring */
|
|
79
|
+
:host([focus-ring]) [part='checkbox'] {
|
|
80
|
+
box-shadow: 0 0 0 1px var(--lumo-base-color), 0 0 0 3px var(--lumo-primary-color-50pct);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* Disabled */
|
|
84
|
+
:host([disabled]) {
|
|
85
|
+
pointer-events: none;
|
|
86
|
+
color: var(--lumo-disabled-text-color);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
:host([disabled]) ::slotted(label) {
|
|
90
|
+
color: inherit;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
:host([disabled]) [part='checkbox'] {
|
|
94
|
+
background-color: var(--lumo-contrast-10pct);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
:host([disabled]) [part='checkbox']::after {
|
|
98
|
+
color: var(--lumo-contrast-30pct);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
:host([indeterminate][disabled]) [part='checkbox']::after {
|
|
102
|
+
background-color: var(--lumo-contrast-30pct);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* RTL specific styles */
|
|
106
|
+
:host([dir='rtl'][has-label]) ::slotted(label) {
|
|
107
|
+
padding: var(--lumo-space-xs) var(--lumo-space-xs) var(--lumo-space-xs) var(--lumo-space-s);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* Used for activation "halo" */
|
|
111
|
+
[part='checkbox']::before {
|
|
112
|
+
pointer-events: none;
|
|
113
|
+
color: transparent;
|
|
114
|
+
width: 100%;
|
|
115
|
+
height: 100%;
|
|
116
|
+
line-height: var(--_checkbox-size);
|
|
117
|
+
border-radius: inherit;
|
|
118
|
+
background-color: inherit;
|
|
119
|
+
transform: scale(1.4);
|
|
120
|
+
opacity: 0;
|
|
121
|
+
transition: transform 0.1s, opacity 0.8s;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/* Hover */
|
|
125
|
+
:host(:not([checked]):not([indeterminate]):not([disabled]):hover) [part='checkbox'] {
|
|
126
|
+
background-color: var(--lumo-contrast-30pct);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* Disable hover for touch devices */
|
|
130
|
+
@media (pointer: coarse) {
|
|
131
|
+
:host(:not([checked]):not([indeterminate]):not([disabled]):hover) [part='checkbox'] {
|
|
132
|
+
background-color: var(--lumo-contrast-20pct);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* Active */
|
|
137
|
+
:host([active]) [part='checkbox'] {
|
|
138
|
+
transform: scale(0.9);
|
|
139
|
+
transition-duration: 0.05s;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
:host([active][checked]) [part='checkbox'] {
|
|
143
|
+
transform: scale(1.1);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
:host([active]:not([checked])) [part='checkbox']::before {
|
|
147
|
+
transition-duration: 0.01s, 0.01s;
|
|
148
|
+
transform: scale(0);
|
|
149
|
+
opacity: 0.4;
|
|
150
|
+
}
|
|
151
|
+
`,
|
|
152
|
+
{ moduleId: 'lumo-checkbox' },
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @license
|
|
157
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
158
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
159
|
+
*/
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* A mixin to manage the checked state.
|
|
163
|
+
*
|
|
164
|
+
* @polymerMixin
|
|
165
|
+
* @mixes DelegateStateMixin
|
|
166
|
+
* @mixes DisabledMixin
|
|
167
|
+
* @mixes InputMixin
|
|
168
|
+
*/
|
|
169
|
+
const CheckedMixin = dedupingMixin(
|
|
170
|
+
(superclass) =>
|
|
171
|
+
class CheckedMixinClass extends DelegateStateMixin(DisabledMixin(InputMixin(superclass))) {
|
|
172
|
+
static get properties() {
|
|
173
|
+
return {
|
|
174
|
+
/**
|
|
175
|
+
* True if the element is checked.
|
|
176
|
+
* @type {boolean}
|
|
177
|
+
*/
|
|
178
|
+
checked: {
|
|
179
|
+
type: Boolean,
|
|
180
|
+
value: false,
|
|
181
|
+
notify: true,
|
|
182
|
+
reflectToAttribute: true,
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
static get delegateProps() {
|
|
188
|
+
return [...super.delegateProps, 'checked'];
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* @param {Event} event
|
|
193
|
+
* @protected
|
|
194
|
+
* @override
|
|
195
|
+
*/
|
|
196
|
+
_onChange(event) {
|
|
197
|
+
const input = event.target;
|
|
198
|
+
|
|
199
|
+
this._toggleChecked(input.checked);
|
|
200
|
+
|
|
201
|
+
// Clicking the checkbox or radio-button in Safari
|
|
202
|
+
// does not make it focused, so we do it manually.
|
|
203
|
+
if (!isElementFocused(input)) {
|
|
204
|
+
input.focus();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** @protected */
|
|
209
|
+
_toggleChecked(checked) {
|
|
210
|
+
this.checked = checked;
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* @license
|
|
217
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
218
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
219
|
+
*/
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* A controller to copy the content from a source slot to a target element.
|
|
223
|
+
*/
|
|
224
|
+
class SlotTargetController {
|
|
225
|
+
constructor(sourceSlot, targetFactory, callback) {
|
|
226
|
+
/**
|
|
227
|
+
* The source `<slot>` element to copy nodes from.
|
|
228
|
+
*/
|
|
229
|
+
this.sourceSlot = sourceSlot;
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Function used to get a reference to slot target.
|
|
233
|
+
*/
|
|
234
|
+
this.targetFactory = targetFactory;
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Function called after copying nodes to target.
|
|
238
|
+
*/
|
|
239
|
+
this.copyCallback = callback;
|
|
240
|
+
|
|
241
|
+
if (sourceSlot) {
|
|
242
|
+
sourceSlot.addEventListener('slotchange', () => {
|
|
243
|
+
// Copy in progress, ignore this event.
|
|
244
|
+
if (this.__copying) {
|
|
245
|
+
this.__copying = false;
|
|
246
|
+
} else {
|
|
247
|
+
this.__checkAndCopyNodesToSlotTarget();
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
hostConnected() {
|
|
254
|
+
this.__sourceSlotObserver = new MutationObserver(() => this.__checkAndCopyNodesToSlotTarget());
|
|
255
|
+
|
|
256
|
+
// Ensure the content is up to date when host is connected
|
|
257
|
+
// to handle e.g. mutating text content while disconnected.
|
|
258
|
+
// Note, `hostConnected()` is called twice if the controller
|
|
259
|
+
// is initialized in `ready()` when using `ControllerMixin`.
|
|
260
|
+
if (!this.__copying) {
|
|
261
|
+
this.__checkAndCopyNodesToSlotTarget();
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Copies every node from the source slot to the target element
|
|
267
|
+
* once the source slot' content is changed.
|
|
268
|
+
*
|
|
269
|
+
* @private
|
|
270
|
+
*/
|
|
271
|
+
__checkAndCopyNodesToSlotTarget() {
|
|
272
|
+
this.__sourceSlotObserver.disconnect();
|
|
273
|
+
|
|
274
|
+
// Ensure slot target element is up to date.
|
|
275
|
+
const slotTarget = this.targetFactory();
|
|
276
|
+
|
|
277
|
+
if (!slotTarget) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Remove any existing clones from the slot target
|
|
282
|
+
if (this.__slotTargetClones) {
|
|
283
|
+
this.__slotTargetClones.forEach((node) => {
|
|
284
|
+
if (node.parentElement === slotTarget) {
|
|
285
|
+
slotTarget.removeChild(node);
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
delete this.__slotTargetClones;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Exclude whitespace text nodes
|
|
292
|
+
const nodes = this.sourceSlot
|
|
293
|
+
.assignedNodes({ flatten: true })
|
|
294
|
+
.filter((node) => !(node.nodeType === Node.TEXT_NODE && node.textContent.trim() === ''));
|
|
295
|
+
|
|
296
|
+
if (nodes.length > 0) {
|
|
297
|
+
slotTarget.innerHTML = '';
|
|
298
|
+
|
|
299
|
+
// Ignore next slotchange
|
|
300
|
+
this.__copying = true;
|
|
301
|
+
|
|
302
|
+
this.__copyNodesToSlotTarget(nodes, slotTarget);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Copies the nodes to the target element.
|
|
308
|
+
*
|
|
309
|
+
* @param {!Array<!Node>} nodes
|
|
310
|
+
* @param {HTMLElement} slotTarget
|
|
311
|
+
* @private
|
|
312
|
+
*/
|
|
313
|
+
__copyNodesToSlotTarget(nodes, slotTarget) {
|
|
314
|
+
this.__slotTargetClones = this.__slotTargetClones || [];
|
|
315
|
+
|
|
316
|
+
nodes.forEach((node) => {
|
|
317
|
+
// Clone the nodes and append the clones to the target
|
|
318
|
+
const clone = node.cloneNode(true);
|
|
319
|
+
this.__slotTargetClones.push(clone);
|
|
320
|
+
|
|
321
|
+
slotTarget.appendChild(clone);
|
|
322
|
+
|
|
323
|
+
// Observe all changes to the source node to have the clones updated
|
|
324
|
+
this.__sourceSlotObserver.observe(node, {
|
|
325
|
+
attributes: true,
|
|
326
|
+
childList: true,
|
|
327
|
+
subtree: true,
|
|
328
|
+
characterData: true,
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
// Run callback e.g. to show a deprecation warning
|
|
333
|
+
if (typeof this.copyCallback === 'function') {
|
|
334
|
+
this.copyCallback(nodes);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* @license
|
|
341
|
+
* Copyright (c) 2017 - 2022 Vaadin Ltd.
|
|
342
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
343
|
+
*/
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* `<vaadin-checkbox>` is an input field representing a binary choice.
|
|
347
|
+
*
|
|
348
|
+
* ```html
|
|
349
|
+
* <vaadin-checkbox label="I accept the terms and conditions"></vaadin-checkbox>
|
|
350
|
+
* ```
|
|
351
|
+
*
|
|
352
|
+
* ### Styling
|
|
353
|
+
*
|
|
354
|
+
* The following shadow DOM parts are available for styling:
|
|
355
|
+
*
|
|
356
|
+
* Part name | Description
|
|
357
|
+
* ------------|----------------
|
|
358
|
+
* `checkbox` | The wrapper element that contains slotted <input type="checkbox">.
|
|
359
|
+
*
|
|
360
|
+
* The following state attributes are available for styling:
|
|
361
|
+
*
|
|
362
|
+
* Attribute | Description | Part name
|
|
363
|
+
* ----------------|-------------|--------------
|
|
364
|
+
* `active` | Set when the checkbox is pressed down, either with mouse, touch or the keyboard. | `:host`
|
|
365
|
+
* `disabled` | Set when the checkbox is disabled. | `:host`
|
|
366
|
+
* `focus-ring` | Set when the checkbox is focused using the keyboard. | `:host`
|
|
367
|
+
* `focused` | Set when the checkbox is focused. | `:host`
|
|
368
|
+
* `indeterminate` | Set when the checkbox is in the indeterminate state. | `:host`
|
|
369
|
+
* `checked` | Set when the checkbox is checked. | `:host`
|
|
370
|
+
* `has-label` | Set when the checkbox has a label. | `:host`
|
|
371
|
+
*
|
|
372
|
+
* See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
|
|
373
|
+
*
|
|
374
|
+
* @fires {CustomEvent} checked-changed - Fired when the `checked` property changes.
|
|
375
|
+
* @fires {CustomEvent} indeterminate-changed - Fired when the `indeterminate` property changes.
|
|
376
|
+
*
|
|
377
|
+
* @extends HTMLElement
|
|
378
|
+
* @mixes ControllerMixin
|
|
379
|
+
* @mixes ThemableMixin
|
|
380
|
+
* @mixes ElementMixin
|
|
381
|
+
* @mixes ActiveMixin
|
|
382
|
+
* @mixes DelegateFocusMixin
|
|
383
|
+
* @mixes CheckedMixin
|
|
384
|
+
* @mixes LabelMixin
|
|
385
|
+
*/
|
|
386
|
+
class Checkbox extends LabelMixin(
|
|
387
|
+
CheckedMixin(DelegateFocusMixin(ActiveMixin(ElementMixin(ThemableMixin(ControllerMixin(PolymerElement)))))),
|
|
388
|
+
) {
|
|
389
|
+
static get is() {
|
|
390
|
+
return 'vaadin-checkbox';
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
static get template() {
|
|
394
|
+
return html`
|
|
395
|
+
<style>
|
|
396
|
+
:host {
|
|
397
|
+
display: inline-block;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
:host([hidden]) {
|
|
401
|
+
display: none !important;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
:host([disabled]) {
|
|
405
|
+
-webkit-tap-highlight-color: transparent;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.vaadin-checkbox-container {
|
|
409
|
+
display: grid;
|
|
410
|
+
grid-template-columns: auto 1fr;
|
|
411
|
+
align-items: baseline;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
[part='checkbox'],
|
|
415
|
+
::slotted(input),
|
|
416
|
+
::slotted(label) {
|
|
417
|
+
grid-row: 1;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
[part='checkbox'],
|
|
421
|
+
::slotted(input) {
|
|
422
|
+
grid-column: 1;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
[part='checkbox'] {
|
|
426
|
+
width: var(--vaadin-checkbox-size, 1em);
|
|
427
|
+
height: var(--vaadin-checkbox-size, 1em);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
[part='checkbox']::before {
|
|
431
|
+
display: block;
|
|
432
|
+
content: '\\202F';
|
|
433
|
+
line-height: var(--vaadin-checkbox-size, 1em);
|
|
434
|
+
contain: paint;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/* visually hidden */
|
|
438
|
+
::slotted(input) {
|
|
439
|
+
opacity: 0;
|
|
440
|
+
cursor: inherit;
|
|
441
|
+
margin: 0;
|
|
442
|
+
align-self: stretch;
|
|
443
|
+
-webkit-appearance: none;
|
|
444
|
+
}
|
|
445
|
+
</style>
|
|
446
|
+
<div class="vaadin-checkbox-container">
|
|
447
|
+
<div part="checkbox"></div>
|
|
448
|
+
<slot name="input"></slot>
|
|
449
|
+
<slot name="label"></slot>
|
|
450
|
+
|
|
451
|
+
<div style="display: none !important">
|
|
452
|
+
<slot id="noop"></slot>
|
|
453
|
+
</div>
|
|
454
|
+
</div>
|
|
455
|
+
<slot name="tooltip"></slot>
|
|
456
|
+
`;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
static get properties() {
|
|
460
|
+
return {
|
|
461
|
+
/**
|
|
462
|
+
* True if the checkbox is in the indeterminate state which means
|
|
463
|
+
* it is not possible to say whether it is checked or unchecked.
|
|
464
|
+
* The state is reset once the user switches the checkbox by hand.
|
|
465
|
+
*
|
|
466
|
+
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#Indeterminate_state_checkboxes
|
|
467
|
+
*
|
|
468
|
+
* @type {boolean}
|
|
469
|
+
*/
|
|
470
|
+
indeterminate: {
|
|
471
|
+
type: Boolean,
|
|
472
|
+
notify: true,
|
|
473
|
+
value: false,
|
|
474
|
+
reflectToAttribute: true,
|
|
475
|
+
},
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* The name of the checkbox.
|
|
479
|
+
*
|
|
480
|
+
* @type {string}
|
|
481
|
+
*/
|
|
482
|
+
name: {
|
|
483
|
+
type: String,
|
|
484
|
+
value: '',
|
|
485
|
+
},
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/** @override */
|
|
490
|
+
static get delegateProps() {
|
|
491
|
+
return [...super.delegateProps, 'indeterminate'];
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/** @override */
|
|
495
|
+
static get delegateAttrs() {
|
|
496
|
+
return [...super.delegateAttrs, 'name'];
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
constructor() {
|
|
500
|
+
super();
|
|
501
|
+
|
|
502
|
+
this._setType('checkbox');
|
|
503
|
+
|
|
504
|
+
// Set the string "on" as the default value for the checkbox following the HTML specification:
|
|
505
|
+
// https://html.spec.whatwg.org/multipage/input.html#dom-input-value-default-on
|
|
506
|
+
this.value = 'on';
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/** @protected */
|
|
510
|
+
ready() {
|
|
511
|
+
super.ready();
|
|
512
|
+
|
|
513
|
+
this.addController(
|
|
514
|
+
new InputController(this, (input) => {
|
|
515
|
+
this._setInputElement(input);
|
|
516
|
+
this._setFocusElement(input);
|
|
517
|
+
this.stateTarget = input;
|
|
518
|
+
this.ariaTarget = input;
|
|
519
|
+
}),
|
|
520
|
+
);
|
|
521
|
+
this.addController(new LabelledInputController(this.inputElement, this._labelController));
|
|
522
|
+
this.addController(
|
|
523
|
+
new SlotTargetController(
|
|
524
|
+
this.$.noop,
|
|
525
|
+
() => this._labelController.node,
|
|
526
|
+
() => this.__warnDeprecated(),
|
|
527
|
+
),
|
|
528
|
+
);
|
|
529
|
+
this._tooltipController = new TooltipController(this);
|
|
530
|
+
this.addController(this._tooltipController);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/** @private */
|
|
534
|
+
__warnDeprecated() {
|
|
535
|
+
console.warn(
|
|
536
|
+
`WARNING: Since Vaadin 22, placing the label as a direct child of a <vaadin-checkbox> is deprecated.
|
|
537
|
+
Please use <label slot="label"> wrapper or the label property instead.`,
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Extends the method from `ActiveMixin` in order to
|
|
543
|
+
* prevent setting the `active` attribute when interacting with a link inside the label.
|
|
544
|
+
*
|
|
545
|
+
* @param {Event} event
|
|
546
|
+
* @return {boolean}
|
|
547
|
+
* @protected
|
|
548
|
+
* @override
|
|
549
|
+
*/
|
|
550
|
+
_shouldSetActive(event) {
|
|
551
|
+
if (event.target.localName === 'a') {
|
|
552
|
+
return false;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
return super._shouldSetActive(event);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Extends the method from `CheckedMixin` in order to
|
|
560
|
+
* reset the indeterminate state once the user switches the checkbox.
|
|
561
|
+
*
|
|
562
|
+
* @param {boolean} checked
|
|
563
|
+
* @protected
|
|
564
|
+
* @override
|
|
565
|
+
*/
|
|
566
|
+
_toggleChecked(checked) {
|
|
567
|
+
if (this.indeterminate) {
|
|
568
|
+
this.indeterminate = false;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
super._toggleChecked(checked);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
customElements.define(Checkbox.is, Checkbox);
|
|
576
|
+
|
|
577
|
+
const checkboxGroup = i`
|
|
578
|
+
:host {
|
|
579
|
+
color: var(--lumo-body-text-color);
|
|
580
|
+
font-size: var(--lumo-font-size-m);
|
|
581
|
+
font-family: var(--lumo-font-family);
|
|
582
|
+
-webkit-font-smoothing: antialiased;
|
|
583
|
+
-moz-osx-font-smoothing: grayscale;
|
|
584
|
+
-webkit-tap-highlight-color: transparent;
|
|
585
|
+
padding: var(--lumo-space-xs) 0;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
:host::before {
|
|
589
|
+
/* Effective height of vaadin-checkbox */
|
|
590
|
+
height: var(--lumo-size-s);
|
|
591
|
+
box-sizing: border-box;
|
|
592
|
+
display: inline-flex;
|
|
593
|
+
align-items: center;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
:host([theme~='vertical']) [part='group-field'] {
|
|
597
|
+
display: flex;
|
|
598
|
+
flex-direction: column;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
:host([disabled]) [part='label'] {
|
|
602
|
+
color: var(--lumo-disabled-text-color);
|
|
603
|
+
-webkit-text-fill-color: var(--lumo-disabled-text-color);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
:host([focused]:not([disabled])) [part='label'] {
|
|
607
|
+
color: var(--lumo-primary-text-color);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
:host(:hover:not([disabled]):not([focused])) [part='label'],
|
|
611
|
+
:host(:hover:not([disabled]):not([focused])) [part='helper-text'] {
|
|
612
|
+
color: var(--lumo-body-text-color);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/* Touch device adjustment */
|
|
616
|
+
@media (pointer: coarse) {
|
|
617
|
+
:host(:hover:not([disabled]):not([focused])) [part='label'] {
|
|
618
|
+
color: var(--lumo-secondary-text-color);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
`;
|
|
622
|
+
|
|
623
|
+
registerStyles('vaadin-checkbox-group', [requiredField, helper, checkboxGroup], {
|
|
624
|
+
moduleId: 'lumo-checkbox-group',
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* @license
|
|
629
|
+
* Copyright (c) 2018 - 2022 Vaadin Ltd.
|
|
630
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
631
|
+
*/
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* `<vaadin-checkbox-group>` is a web component that allows the user to choose several items from a group of binary choices.
|
|
635
|
+
*
|
|
636
|
+
* ```html
|
|
637
|
+
* <vaadin-checkbox-group label="Preferred language of contact:">
|
|
638
|
+
* <vaadin-checkbox value="en" label="English"></vaadin-checkbox>
|
|
639
|
+
* <vaadin-checkbox value="fr" label="Français"></vaadin-checkbox>
|
|
640
|
+
* <vaadin-checkbox value="de" label="Deutsch"></vaadin-checkbox>
|
|
641
|
+
* </vaadin-checkbox-group>
|
|
642
|
+
* ```
|
|
643
|
+
*
|
|
644
|
+
* ### Styling
|
|
645
|
+
*
|
|
646
|
+
* The following shadow DOM parts are available for styling:
|
|
647
|
+
*
|
|
648
|
+
* Part name | Description
|
|
649
|
+
* ---------------------|----------------
|
|
650
|
+
* `label` | The slotted label element wrapper
|
|
651
|
+
* `group-field` | The checkbox elements wrapper
|
|
652
|
+
* `helper-text` | The slotted helper text element wrapper
|
|
653
|
+
* `error-message` | The slotted error message element wrapper
|
|
654
|
+
* `required-indicator` | The `required` state indicator element
|
|
655
|
+
*
|
|
656
|
+
* The following state attributes are available for styling:
|
|
657
|
+
*
|
|
658
|
+
* Attribute | Description | Part name
|
|
659
|
+
* --------------------|-------------------------------------------|------------
|
|
660
|
+
* `disabled` | Set when the element is disabled | :host
|
|
661
|
+
* `invalid` | Set when the element is invalid | :host
|
|
662
|
+
* `focused` | Set when the element is focused | :host
|
|
663
|
+
* `has-label` | Set when the element has a label | :host
|
|
664
|
+
* `has-value` | Set when the element has a value | :host
|
|
665
|
+
* `has-helper` | Set when the element has helper text | :host
|
|
666
|
+
* `has-error-message` | Set when the element has an error message | :host
|
|
667
|
+
*
|
|
668
|
+
* See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
|
|
669
|
+
*
|
|
670
|
+
* @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
|
|
671
|
+
* @fires {CustomEvent} value-changed - Fired when the `value` property changes.
|
|
672
|
+
* @fires {CustomEvent} validated - Fired whenever the field is validated.
|
|
673
|
+
*
|
|
674
|
+
* @extends HTMLElement
|
|
675
|
+
* @mixes ThemableMixin
|
|
676
|
+
* @mixes DisabledMixin
|
|
677
|
+
* @mixes ElementMixin
|
|
678
|
+
* @mixes FocusMixin
|
|
679
|
+
* @mixes FieldMixin
|
|
680
|
+
*/
|
|
681
|
+
class CheckboxGroup extends FieldMixin(FocusMixin(DisabledMixin(ElementMixin(ThemableMixin(PolymerElement))))) {
|
|
682
|
+
static get is() {
|
|
683
|
+
return 'vaadin-checkbox-group';
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
static get template() {
|
|
687
|
+
return html`
|
|
688
|
+
<style>
|
|
689
|
+
:host {
|
|
690
|
+
display: inline-flex;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
:host::before {
|
|
694
|
+
content: '\\2003';
|
|
695
|
+
width: 0;
|
|
696
|
+
display: inline-block;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
:host([hidden]) {
|
|
700
|
+
display: none !important;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
.vaadin-group-field-container {
|
|
704
|
+
display: flex;
|
|
705
|
+
flex-direction: column;
|
|
706
|
+
width: 100%;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
:host(:not([has-label])) [part='label'] {
|
|
710
|
+
display: none;
|
|
711
|
+
}
|
|
712
|
+
</style>
|
|
713
|
+
|
|
714
|
+
<div class="vaadin-group-field-container">
|
|
715
|
+
<div part="label">
|
|
716
|
+
<slot name="label"></slot>
|
|
717
|
+
<span part="required-indicator" aria-hidden="true"></span>
|
|
718
|
+
</div>
|
|
719
|
+
|
|
720
|
+
<div part="group-field">
|
|
721
|
+
<slot></slot>
|
|
722
|
+
</div>
|
|
723
|
+
|
|
724
|
+
<div part="helper-text">
|
|
725
|
+
<slot name="helper"></slot>
|
|
726
|
+
</div>
|
|
727
|
+
|
|
728
|
+
<div part="error-message">
|
|
729
|
+
<slot name="error-message"></slot>
|
|
730
|
+
</div>
|
|
731
|
+
</div>
|
|
732
|
+
|
|
733
|
+
<slot name="tooltip"></slot>
|
|
734
|
+
`;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
static get properties() {
|
|
738
|
+
return {
|
|
739
|
+
/**
|
|
740
|
+
* An array containing values of the currently checked checkboxes.
|
|
741
|
+
*
|
|
742
|
+
* The array is immutable so toggling checkboxes always results in
|
|
743
|
+
* creating a new array.
|
|
744
|
+
*
|
|
745
|
+
* @type {!Array<!string>}
|
|
746
|
+
*/
|
|
747
|
+
value: {
|
|
748
|
+
type: Array,
|
|
749
|
+
value: () => [],
|
|
750
|
+
notify: true,
|
|
751
|
+
observer: '__valueChanged',
|
|
752
|
+
},
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
constructor() {
|
|
757
|
+
super();
|
|
758
|
+
|
|
759
|
+
this.__registerCheckbox = this.__registerCheckbox.bind(this);
|
|
760
|
+
this.__unregisterCheckbox = this.__unregisterCheckbox.bind(this);
|
|
761
|
+
this.__onCheckboxCheckedChanged = this.__onCheckboxCheckedChanged.bind(this);
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
/** @protected */
|
|
765
|
+
ready() {
|
|
766
|
+
super.ready();
|
|
767
|
+
|
|
768
|
+
this.ariaTarget = this;
|
|
769
|
+
|
|
770
|
+
// See https://github.com/vaadin/vaadin-web-components/issues/94
|
|
771
|
+
this.setAttribute('role', 'group');
|
|
772
|
+
|
|
773
|
+
this._observer = new FlattenedNodesObserver(this, ({ addedNodes, removedNodes }) => {
|
|
774
|
+
const addedCheckboxes = this.__filterCheckboxes(addedNodes);
|
|
775
|
+
const removedCheckboxes = this.__filterCheckboxes(removedNodes);
|
|
776
|
+
|
|
777
|
+
addedCheckboxes.forEach(this.__registerCheckbox);
|
|
778
|
+
removedCheckboxes.forEach(this.__unregisterCheckbox);
|
|
779
|
+
|
|
780
|
+
this.__warnOfCheckboxesWithoutValue(addedCheckboxes);
|
|
781
|
+
});
|
|
782
|
+
|
|
783
|
+
this._tooltipController = new TooltipController(this);
|
|
784
|
+
this.addController(this._tooltipController);
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* Override method inherited from `ValidateMixin`
|
|
789
|
+
* to validate the value array.
|
|
790
|
+
*
|
|
791
|
+
* @override
|
|
792
|
+
* @return {boolean}
|
|
793
|
+
*/
|
|
794
|
+
checkValidity() {
|
|
795
|
+
return !this.required || this.value.length > 0;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
/**
|
|
799
|
+
* @param {!Array<!Node>} nodes
|
|
800
|
+
* @return {!Array<!Checkbox>}
|
|
801
|
+
* @private
|
|
802
|
+
*/
|
|
803
|
+
__filterCheckboxes(nodes) {
|
|
804
|
+
return nodes.filter((child) => child instanceof Checkbox);
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* A collection of the checkboxes.
|
|
809
|
+
*
|
|
810
|
+
* @return {!Array<!Checkbox>}
|
|
811
|
+
* @private
|
|
812
|
+
*/
|
|
813
|
+
get __checkboxes() {
|
|
814
|
+
return this.__filterCheckboxes([...this.children]);
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
/**
|
|
818
|
+
* @param {!Array<!Checkbox>} checkboxes
|
|
819
|
+
* @private
|
|
820
|
+
*/
|
|
821
|
+
__warnOfCheckboxesWithoutValue(checkboxes) {
|
|
822
|
+
const hasCheckboxesWithoutValue = checkboxes.some((checkbox) => {
|
|
823
|
+
const { value } = checkbox;
|
|
824
|
+
|
|
825
|
+
return !checkbox.hasAttribute('value') && (!value || value === 'on');
|
|
826
|
+
});
|
|
827
|
+
|
|
828
|
+
if (hasCheckboxesWithoutValue) {
|
|
829
|
+
console.warn('Please provide the value attribute to all the checkboxes inside the checkbox group.');
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* Registers the checkbox after adding it to the group.
|
|
835
|
+
*
|
|
836
|
+
* @param {!Checkbox} checkbox
|
|
837
|
+
* @private
|
|
838
|
+
*/
|
|
839
|
+
__registerCheckbox(checkbox) {
|
|
840
|
+
checkbox.addEventListener('checked-changed', this.__onCheckboxCheckedChanged);
|
|
841
|
+
|
|
842
|
+
if (this.disabled) {
|
|
843
|
+
checkbox.disabled = true;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
if (checkbox.checked) {
|
|
847
|
+
this.__addCheckboxToValue(checkbox.value);
|
|
848
|
+
} else if (this.value.includes(checkbox.value)) {
|
|
849
|
+
checkbox.checked = true;
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
/**
|
|
854
|
+
* Unregisters the checkbox before removing it from the group.
|
|
855
|
+
*
|
|
856
|
+
* @param {!Checkbox} checkbox
|
|
857
|
+
* @private
|
|
858
|
+
*/
|
|
859
|
+
__unregisterCheckbox(checkbox) {
|
|
860
|
+
checkbox.removeEventListener('checked-changed', this.__onCheckboxCheckedChanged);
|
|
861
|
+
|
|
862
|
+
if (checkbox.checked) {
|
|
863
|
+
this.__removeCheckboxFromValue(checkbox.value);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
/**
|
|
868
|
+
* Override method inherited from `DisabledMixin`
|
|
869
|
+
* to propagate the `disabled` property to the checkboxes.
|
|
870
|
+
*
|
|
871
|
+
* @param {boolean} newValue
|
|
872
|
+
* @param {boolean} oldValue
|
|
873
|
+
* @override
|
|
874
|
+
* @protected
|
|
875
|
+
*/
|
|
876
|
+
_disabledChanged(newValue, oldValue) {
|
|
877
|
+
super._disabledChanged(newValue, oldValue);
|
|
878
|
+
|
|
879
|
+
// Prevent updating the `disabled` property for the checkboxes at initialization.
|
|
880
|
+
// Otherwise, the checkboxes may end up enabled regardless the `disabled` attribute
|
|
881
|
+
// intentionally added by the user on some of them.
|
|
882
|
+
if (!newValue && oldValue === undefined) {
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
if (oldValue !== newValue) {
|
|
887
|
+
this.__checkboxes.forEach((checkbox) => {
|
|
888
|
+
checkbox.disabled = newValue;
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
/**
|
|
894
|
+
* @param {string} value
|
|
895
|
+
* @private
|
|
896
|
+
*/
|
|
897
|
+
__addCheckboxToValue(value) {
|
|
898
|
+
if (!this.value.includes(value)) {
|
|
899
|
+
this.value = [...this.value, value];
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
/**
|
|
904
|
+
* @param {string} value
|
|
905
|
+
* @private
|
|
906
|
+
*/
|
|
907
|
+
__removeCheckboxFromValue(value) {
|
|
908
|
+
if (this.value.includes(value)) {
|
|
909
|
+
this.value = this.value.filter((v) => v !== value);
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
/**
|
|
914
|
+
* @param {!CustomEvent} event
|
|
915
|
+
* @private
|
|
916
|
+
*/
|
|
917
|
+
__onCheckboxCheckedChanged(event) {
|
|
918
|
+
const checkbox = event.target;
|
|
919
|
+
|
|
920
|
+
if (checkbox.checked) {
|
|
921
|
+
this.__addCheckboxToValue(checkbox.value);
|
|
922
|
+
} else {
|
|
923
|
+
this.__removeCheckboxFromValue(checkbox.value);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
/**
|
|
928
|
+
* @param {string | null | undefined} value
|
|
929
|
+
* @param {string | null | undefined} oldValue
|
|
930
|
+
* @private
|
|
931
|
+
*/
|
|
932
|
+
__valueChanged(value, oldValue) {
|
|
933
|
+
// Setting initial value to empty array, skip validation
|
|
934
|
+
if (value.length === 0 && oldValue === undefined) {
|
|
935
|
+
return;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
this.toggleAttribute('has-value', value.length > 0);
|
|
939
|
+
|
|
940
|
+
this.__checkboxes.forEach((checkbox) => {
|
|
941
|
+
checkbox.checked = value.includes(checkbox.value);
|
|
942
|
+
});
|
|
943
|
+
|
|
944
|
+
if (oldValue !== undefined) {
|
|
945
|
+
this.validate();
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
/**
|
|
950
|
+
* Override method inherited from `FocusMixin`
|
|
951
|
+
* to prevent removing the `focused` attribute
|
|
952
|
+
* when focus moves between checkboxes inside the group.
|
|
953
|
+
*
|
|
954
|
+
* @param {!FocusEvent} event
|
|
955
|
+
* @return {boolean}
|
|
956
|
+
* @protected
|
|
957
|
+
*/
|
|
958
|
+
_shouldRemoveFocus(event) {
|
|
959
|
+
return !this.contains(event.relatedTarget);
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
/**
|
|
963
|
+
* Override method inherited from `FocusMixin`
|
|
964
|
+
* to run validation when the group loses focus.
|
|
965
|
+
*
|
|
966
|
+
* @param {boolean} focused
|
|
967
|
+
* @override
|
|
968
|
+
* @protected
|
|
969
|
+
*/
|
|
970
|
+
_setFocused(focused) {
|
|
971
|
+
super._setFocused(focused);
|
|
972
|
+
|
|
973
|
+
if (!focused) {
|
|
974
|
+
this.validate();
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
customElements.define(CheckboxGroup.is, CheckboxGroup);
|
|
980
|
+
|
|
981
|
+
const checkboxGroupInputCss = "*,*::before,*::after{padding:0;margin:0;box-sizing:border-box}.checkboxgroup{font-family:\"Roboto\";font-style:normal;font-size:15px}.checkboxgroup__wrapper{position:relative}.checkboxgroup__wrapper--flex{display:flex;gap:5px;align-content:flex-start}.checkboxgroup__wrapper--relative{position:relative;display:inline}.checkboxgroup__label{font-style:inherit;font-family:inherit;font-weight:400;font-size:16px;color:#2B2D3F;line-height:14px}.checkboxgroup__label-text{font-size:16px}.checkboxgroup__error-message{position:absolute;top:calc(100% + 5px);left:0;color:#cc0000b3}.checkboxgroup__tooltip-icon{width:16px;height:auto}.checkboxgroup__tooltip{position:absolute;top:0;right:0;background-color:#FFFFFF;border:1px solid #B0B0B0;color:#2B2D3F;padding:10px;border-radius:5px;opacity:0;transition:opacity 0.3s ease-in-out;z-index:10}.checkboxgroup__tooltip.visible{opacity:1}";
|
|
982
|
+
|
|
983
|
+
const CheckboxGroupInput = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
|
|
984
|
+
constructor() {
|
|
985
|
+
super();
|
|
986
|
+
this.__registerHost();
|
|
987
|
+
this.__attachShadow();
|
|
988
|
+
this.sendValidityState = createEvent(this, "sendValidityState", 7);
|
|
989
|
+
this.sendInputValue = createEvent(this, "sendInputValue", 7);
|
|
990
|
+
/**
|
|
991
|
+
* Default value for the input.
|
|
992
|
+
*/
|
|
993
|
+
this.defaultValue = '';
|
|
994
|
+
/**
|
|
995
|
+
* Client custom styling via inline style
|
|
996
|
+
*/
|
|
997
|
+
this.clientStyling = '';
|
|
998
|
+
this.limitStylingAppends = false;
|
|
999
|
+
this.showTooltip = false;
|
|
1000
|
+
this.selectedValues = [];
|
|
1001
|
+
this.value = null;
|
|
1002
|
+
this.setClientStyling = () => {
|
|
1003
|
+
let sheet = document.createElement('style');
|
|
1004
|
+
sheet.innerHTML = this.clientStyling;
|
|
1005
|
+
this.stylingContainer.prepend(sheet);
|
|
1006
|
+
};
|
|
1007
|
+
}
|
|
1008
|
+
validityChanged() {
|
|
1009
|
+
this.validityStateHandler({ valid: this.isValid, name: this.name });
|
|
1010
|
+
if (this.emitValue == true) {
|
|
1011
|
+
this.valueHandler({ name: this.name, value: this.value, type: 'checkboxgroup' });
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
setValue() {
|
|
1015
|
+
this.value = this.options.reduce((acc, option) => {
|
|
1016
|
+
acc[option.name] = this.selectedValues.includes(option.name);
|
|
1017
|
+
return acc;
|
|
1018
|
+
}, {});
|
|
1019
|
+
this.emitValueHandler(true);
|
|
1020
|
+
}
|
|
1021
|
+
validityStateHandler(inputStateEvent) {
|
|
1022
|
+
this.sendValidityState.emit(inputStateEvent);
|
|
1023
|
+
}
|
|
1024
|
+
emitValueHandler(newValue) {
|
|
1025
|
+
if (newValue == true && this.isValid) {
|
|
1026
|
+
this.valueHandler({ name: this.name, value: this.value, type: 'checkboxgroup' });
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
valueHandler(inputValueEvent) {
|
|
1030
|
+
this.sendInputValue.emit(inputValueEvent);
|
|
1031
|
+
}
|
|
1032
|
+
handleClickOutside(event) {
|
|
1033
|
+
if (event.composedPath()[0] === this.tooltipIconReference)
|
|
1034
|
+
return;
|
|
1035
|
+
if (event.composedPath()[0] !== this.tooltipReference)
|
|
1036
|
+
this.showTooltip = false;
|
|
1037
|
+
}
|
|
1038
|
+
componentDidRender() {
|
|
1039
|
+
// start custom styling area
|
|
1040
|
+
if (!this.limitStylingAppends && this.stylingContainer) {
|
|
1041
|
+
if (this.clientStyling)
|
|
1042
|
+
this.setClientStyling();
|
|
1043
|
+
this.limitStylingAppends = true;
|
|
1044
|
+
}
|
|
1045
|
+
// end custom styling area
|
|
1046
|
+
}
|
|
1047
|
+
componentDidLoad() {
|
|
1048
|
+
this.inputReference = this.element.shadowRoot.querySelector('input');
|
|
1049
|
+
// For now this input has no validation. Send isValid as true immediately.
|
|
1050
|
+
//@TODO: add validation logic to it, if business reason arises.
|
|
1051
|
+
this.isValid = this.setValidity();
|
|
1052
|
+
if (this.defaultValue) {
|
|
1053
|
+
this.selectedValues = this.options.map((checkbox) => checkbox.name);
|
|
1054
|
+
this.value = this.defaultValue;
|
|
1055
|
+
this.valueHandler({ name: this.name, value: this.value });
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
setValidity() {
|
|
1059
|
+
return this.inputReference.validity.valid;
|
|
1060
|
+
}
|
|
1061
|
+
setErrorMessage() {
|
|
1062
|
+
if (this.inputReference.validity.valueMissing) {
|
|
1063
|
+
return translate('requiredError', this.language);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
renderTooltip() {
|
|
1067
|
+
if (this.showTooltip) {
|
|
1068
|
+
return (h("div", { class: `checkboxgroup__tooltip ${this.showTooltip ? 'visible' : ''}`, ref: (el) => this.tooltipReference = el, innerHTML: this.tooltip }));
|
|
1069
|
+
}
|
|
1070
|
+
return null;
|
|
1071
|
+
}
|
|
1072
|
+
handleParentCheckbox(e) {
|
|
1073
|
+
// Logic for toggling the children checkboxes.
|
|
1074
|
+
this.selectedValues = e.target.checked
|
|
1075
|
+
? this.options.map((checkbox) => checkbox.name)
|
|
1076
|
+
: [];
|
|
1077
|
+
}
|
|
1078
|
+
renderLabel() {
|
|
1079
|
+
return (h("label", { class: 'checkbox__label', htmlFor: `${this.name}__input`, slot: 'label' }, h("div", { class: 'checkbox__label-text', innerHTML: `${this.displayName} ${this.validation.mandatory ? '*' : ''}` })));
|
|
1080
|
+
}
|
|
1081
|
+
render() {
|
|
1082
|
+
return h("div", { class: `checkboxgroup__wrapper ${this.name}__input`, ref: el => this.stylingContainer = el }, h("div", { class: 'checkboxgroup__wrapper--flex' }, h("vaadin-checkbox", { class: 'checkbox__input', checked: this.selectedValues.length === this.options.length || this.defaultValue === 'true', indeterminate: this.selectedValues.length > 0 && this.selectedValues.length < this.options.length, onChange: (e) => this.handleParentCheckbox(e) }, this.renderLabel()), this.tooltip &&
|
|
1083
|
+
h("img", { class: 'checkboxgroup__tooltip-icon', src: tooltipIconSvg, alt: "", ref: (el) => this.tooltipIconReference = el, onClick: () => this.showTooltip = !this.showTooltip }), this.renderTooltip()), h("small", { class: 'checkboxgroup__error-message' }, this.errorMessage), h("vaadin-checkbox-group", { theme: "vertical", value: this.selectedValues, "on-value-changed": (event) => {
|
|
1084
|
+
this.selectedValues = event.detail.value;
|
|
1085
|
+
} }, this.options.map((checkbox) => h("vaadin-checkbox", { class: 'checkbox__input', name: checkbox.name, value: checkbox.name, label: checkbox.displayName }))));
|
|
1086
|
+
}
|
|
1087
|
+
get element() { return this; }
|
|
1088
|
+
static get watchers() { return {
|
|
1089
|
+
"isValid": ["validityChanged"],
|
|
1090
|
+
"selectedValues": ["setValue"],
|
|
1091
|
+
"emitValue": ["emitValueHandler"]
|
|
1092
|
+
}; }
|
|
1093
|
+
static get style() { return checkboxGroupInputCss; }
|
|
1094
|
+
}, [1, "checkbox-group-input", {
|
|
1095
|
+
"name": [513],
|
|
1096
|
+
"displayName": [513, "display-name"],
|
|
1097
|
+
"defaultValue": [513, "default-value"],
|
|
1098
|
+
"autofilled": [516],
|
|
1099
|
+
"tooltip": [513],
|
|
1100
|
+
"options": [16],
|
|
1101
|
+
"validation": [16],
|
|
1102
|
+
"language": [513],
|
|
1103
|
+
"emitValue": [516, "emit-value"],
|
|
1104
|
+
"clientStyling": [513, "client-styling"],
|
|
1105
|
+
"errorMessage": [32],
|
|
1106
|
+
"isValid": [32],
|
|
1107
|
+
"limitStylingAppends": [32],
|
|
1108
|
+
"showTooltip": [32],
|
|
1109
|
+
"selectedValues": [32]
|
|
1110
|
+
}, [[4, "click", "handleClickOutside"]]]);
|
|
1111
|
+
function defineCustomElement() {
|
|
1112
|
+
if (typeof customElements === "undefined") {
|
|
1113
|
+
return;
|
|
1114
|
+
}
|
|
1115
|
+
const components = ["checkbox-group-input"];
|
|
1116
|
+
components.forEach(tagName => { switch (tagName) {
|
|
1117
|
+
case "checkbox-group-input":
|
|
1118
|
+
if (!customElements.get(tagName)) {
|
|
1119
|
+
customElements.define(tagName, CheckboxGroupInput);
|
|
1120
|
+
}
|
|
1121
|
+
break;
|
|
1122
|
+
} });
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
export { CheckboxGroupInput as C, defineCustomElement as d };
|