@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.
Files changed (96) hide show
  1. package/dist/cjs/checkbox-group-input_10.cjs.entry.js +35539 -0
  2. package/dist/cjs/general-input.cjs.entry.js +34 -13
  3. package/dist/cjs/general-input.cjs.js +2 -2
  4. package/dist/cjs/{index-64a5cb7f.js → index-132a0774.js} +119 -6
  5. package/dist/cjs/loader.cjs.js +2 -2
  6. package/dist/cjs/locale.utils-7665b010.js +71 -0
  7. package/dist/cjs/toggle-checkbox-input.cjs.entry.js +85 -0
  8. package/dist/cjs/tooltipIcon-092a795f.js +5 -0
  9. package/dist/collection/collection-manifest.json +3 -1
  10. package/dist/collection/components/checkbox-group-input/checkbox-group-input.css +62 -0
  11. package/dist/collection/components/checkbox-group-input/checkbox-group-input.js +366 -0
  12. package/dist/collection/components/checkbox-input/checkbox-input.css +47 -1
  13. package/dist/collection/components/checkbox-input/checkbox-input.js +143 -16
  14. package/dist/collection/components/date-input/date-input.css +64 -30
  15. package/dist/collection/components/date-input/date-input.js +194 -13
  16. package/dist/collection/components/email-input/email-input.css +63 -28
  17. package/dist/collection/components/email-input/email-input.js +197 -21
  18. package/dist/collection/components/general-input/general-input.js +163 -21
  19. package/dist/collection/components/number-input/number-input.css +65 -30
  20. package/dist/collection/components/number-input/number-input.js +174 -19
  21. package/dist/collection/components/password-input/password-input.css +120 -29
  22. package/dist/collection/components/password-input/password-input.js +341 -25
  23. package/dist/collection/components/radio-input/radio-input.css +22 -1
  24. package/dist/collection/components/radio-input/radio-input.js +89 -10
  25. package/dist/collection/components/select-input/select-input.css +75 -22
  26. package/dist/collection/components/select-input/select-input.js +180 -37
  27. package/dist/collection/components/tel-input/tel-input.css +91 -33
  28. package/dist/collection/components/tel-input/tel-input.js +202 -24
  29. package/dist/collection/components/text-input/text-input.css +63 -28
  30. package/dist/collection/components/text-input/text-input.js +208 -39
  31. package/dist/collection/components/toggle-checkbox-input/toggle-checkbox-input.css +76 -0
  32. package/dist/collection/components/toggle-checkbox-input/toggle-checkbox-input.js +324 -0
  33. package/dist/collection/utils/locale.utils.js +52 -13
  34. package/dist/collection/utils/tooltipIcon.svg +5 -0
  35. package/dist/components/active-mixin.js +975 -0
  36. package/dist/components/checkbox-group-input.d.ts +11 -0
  37. package/dist/components/checkbox-group-input.js +6 -0
  38. package/dist/components/checkbox-group-input2.js +1125 -0
  39. package/dist/components/checkbox-input2.js +62 -12
  40. package/dist/components/date-input2.js +10247 -15
  41. package/dist/components/email-input2.js +98 -21
  42. package/dist/components/field-mixin.js +12712 -0
  43. package/dist/components/general-input.js +1 -118
  44. package/dist/components/general-input2.js +331 -0
  45. package/dist/components/input-field-shared-styles.js +1114 -0
  46. package/dist/components/number-input2.js +92 -16
  47. package/dist/components/password-input2.js +924 -24
  48. package/dist/components/pattern-mixin.js +85 -0
  49. package/dist/components/radio-input2.js +45 -11
  50. package/dist/components/select-input2.js +87 -27
  51. package/dist/components/tel-input2.js +122 -22
  52. package/dist/components/text-input2.js +120 -34
  53. package/dist/components/toggle-checkbox-input.d.ts +11 -0
  54. package/dist/components/toggle-checkbox-input.js +6 -0
  55. package/dist/components/tooltipIcon.js +70 -0
  56. package/dist/components/vaadin-button.js +461 -0
  57. package/dist/components/vaadin-combo-box.js +4329 -0
  58. package/dist/components/virtual-keyboard-controller.js +2658 -0
  59. package/dist/esm/checkbox-group-input_10.entry.js +35526 -0
  60. package/dist/esm/general-input.entry.js +34 -13
  61. package/dist/esm/general-input.js +2 -2
  62. package/dist/esm/{index-df80f936.js → index-db76d5b5.js} +118 -7
  63. package/dist/esm/loader.js +2 -2
  64. package/dist/esm/locale.utils-95ea2605.js +68 -0
  65. package/dist/esm/toggle-checkbox-input.entry.js +81 -0
  66. package/dist/esm/tooltipIcon-99c1c7b7.js +3 -0
  67. package/dist/general-input/general-input.esm.js +1 -1
  68. package/dist/general-input/p-0966f523.entry.js +3581 -0
  69. package/dist/general-input/p-916a1319.entry.js +1 -0
  70. package/dist/general-input/p-b408093e.js +1 -0
  71. package/dist/general-input/p-c2d4d6ac.entry.js +1 -0
  72. package/dist/general-input/p-f4f4ccda.js +1 -0
  73. package/dist/general-input/p-f6132f1d.js +1 -0
  74. package/dist/types/components/checkbox-group-input/checkbox-group-input.d.ts +74 -0
  75. package/dist/types/components/checkbox-input/checkbox-input.d.ts +28 -2
  76. package/dist/types/components/date-input/date-input.d.ts +43 -1
  77. package/dist/types/components/email-input/email-input.d.ts +37 -3
  78. package/dist/types/components/general-input/general-input.d.ts +30 -0
  79. package/dist/types/components/number-input/number-input.d.ts +34 -3
  80. package/dist/types/components/password-input/password-input.d.ts +56 -7
  81. package/dist/types/components/radio-input/radio-input.d.ts +17 -1
  82. package/dist/types/components/select-input/select-input.d.ts +36 -3
  83. package/dist/types/components/tel-input/tel-input.d.ts +40 -5
  84. package/dist/types/components/text-input/text-input.d.ts +84 -0
  85. package/dist/types/components/toggle-checkbox-input/toggle-checkbox-input.d.ts +67 -0
  86. package/dist/types/components.d.ts +568 -9
  87. package/dist/types/utils/locale.utils.d.ts +9 -0
  88. package/dist/types/utils/types.d.ts +41 -9
  89. package/package.json +8 -1
  90. package/dist/cjs/checkbox-input_9.cjs.entry.js +0 -623
  91. package/dist/components/locale.utils.js +0 -29
  92. package/dist/esm/checkbox-input_9.entry.js +0 -611
  93. package/dist/general-input/p-1703fce3.entry.js +0 -1
  94. package/dist/general-input/p-d9f7fa2e.js +0 -1
  95. package/dist/general-input/p-dea0a4ac.entry.js +0 -1
  96. /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 };