@vaadin/radio-group 24.2.0-alpha1 → 24.2.0-alpha10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/radio-group",
3
- "version": "24.2.0-alpha1",
3
+ "version": "24.2.0-alpha10",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -38,21 +38,21 @@
38
38
  ],
39
39
  "dependencies": {
40
40
  "@polymer/polymer": "^3.0.0",
41
- "@vaadin/a11y-base": "24.2.0-alpha1",
42
- "@vaadin/component-base": "24.2.0-alpha1",
43
- "@vaadin/field-base": "24.2.0-alpha1",
44
- "@vaadin/vaadin-lumo-styles": "24.2.0-alpha1",
45
- "@vaadin/vaadin-material-styles": "24.2.0-alpha1",
46
- "@vaadin/vaadin-themable-mixin": "24.2.0-alpha1"
41
+ "@vaadin/a11y-base": "24.2.0-alpha10",
42
+ "@vaadin/component-base": "24.2.0-alpha10",
43
+ "@vaadin/field-base": "24.2.0-alpha10",
44
+ "@vaadin/vaadin-lumo-styles": "24.2.0-alpha10",
45
+ "@vaadin/vaadin-material-styles": "24.2.0-alpha10",
46
+ "@vaadin/vaadin-themable-mixin": "24.2.0-alpha10"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@esm-bundle/chai": "^4.3.4",
50
- "@vaadin/testing-helpers": "^0.4.2",
50
+ "@vaadin/testing-helpers": "^0.5.0",
51
51
  "sinon": "^13.0.2"
52
52
  },
53
53
  "web-types": [
54
54
  "web-types.json",
55
55
  "web-types.lit.json"
56
56
  ],
57
- "gitHead": "0dbb118320203ab6c0c07450a3e718815367589f"
57
+ "gitHead": "ca16b5f88b00ae05fb6d7c7e9874525048e389f0"
58
58
  }
@@ -16,8 +16,15 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
16
16
  */
17
17
  export type RadioButtonCheckedChangedEvent = CustomEvent<{ value: boolean }>;
18
18
 
19
+ /**
20
+ * Fired when the `dirty` property changes.
21
+ */
22
+ export type RadioButtonDirtyChangedEvent = CustomEvent<{ value: boolean }>;
23
+
19
24
  export interface RadioButtonCustomEventMap {
20
25
  'checked-changed': RadioButtonCheckedChangedEvent;
26
+
27
+ 'dirty-changed': RadioButtonDirtyChangedEvent;
21
28
  }
22
29
 
23
30
  export interface RadioButtonEventMap extends HTMLElementEventMap, RadioButtonCustomEventMap {}
@@ -56,6 +63,7 @@ export interface RadioButtonEventMap extends HTMLElementEventMap, RadioButtonCus
56
63
  * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
57
64
  *
58
65
  * @fires {CustomEvent} checked-changed - Fired when the `checked` property changes.
66
+ * @fires {CustomEvent} dirty-changed - Fired when the `dirty` property changes.
59
67
  */
60
68
  declare class RadioButton extends LabelMixin(
61
69
  CheckedMixin(DelegateFocusMixin(ActiveMixin(ElementMixin(ThemableMixin(ControllerMixin(HTMLElement)))))),
@@ -48,6 +48,7 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
48
48
  * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
49
49
  *
50
50
  * @fires {CustomEvent} checked-changed - Fired when the `checked` property changes.
51
+ * @fires {CustomEvent} dirty-changed - Fired when the `dirty` property changes.
51
52
  *
52
53
  * @extends HTMLElement
53
54
  * @mixes ControllerMixin
@@ -15,6 +15,11 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
15
15
  */
16
16
  export type RadioGroupInvalidChangedEvent = CustomEvent<{ value: boolean }>;
17
17
 
18
+ /**
19
+ * Fired when the `dirty` property changes.
20
+ */
21
+ export type RadioGroupDirtyChangedEvent = CustomEvent<{ value: boolean }>;
22
+
18
23
  /**
19
24
  * Fired when the `value` property changes.
20
25
  */
@@ -28,6 +33,8 @@ export type RadioGroupValidatedEvent = CustomEvent<{ valid: boolean }>;
28
33
  export interface RadioGroupCustomEventMap {
29
34
  'invalid-changed': RadioGroupInvalidChangedEvent;
30
35
 
36
+ 'dirty-changed': RadioGroupDirtyChangedEvent;
37
+
31
38
  'value-changed': RadioGroupValueChangedEvent;
32
39
 
33
40
  validated: RadioGroupValidatedEvent;
@@ -74,6 +81,7 @@ export interface RadioGroupEventMap extends HTMLElementEventMap, RadioGroupCusto
74
81
  * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
75
82
  *
76
83
  * @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
84
+ * @fires {CustomEvent} dirty-changed - Fired when the `dirty` property changes.
77
85
  * @fires {CustomEvent} value-changed - Fired when the `value` property changes.
78
86
  * @fires {CustomEvent} validated - Fired whenever the field is validated.
79
87
  */
@@ -93,6 +101,15 @@ declare class RadioGroup extends FieldMixin(
93
101
  */
94
102
  readonly: boolean;
95
103
 
104
+ /**
105
+ * Whether the field is dirty.
106
+ *
107
+ * The field is automatically marked as dirty once the user triggers
108
+ * a `change` event. Additionally, the field can be manually marked
109
+ * as dirty by setting the property to `true`.
110
+ */
111
+ dirty: boolean;
112
+
96
113
  addEventListener<K extends keyof RadioGroupEventMap>(
97
114
  type: K,
98
115
  listener: (this: RadioGroup, ev: RadioGroupEventMap[K]) => void,
@@ -3,12 +3,12 @@
3
3
  * Copyright (c) 2017 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js';
7
6
  import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
8
7
  import { DisabledMixin } from '@vaadin/a11y-base/src/disabled-mixin.js';
9
8
  import { FocusMixin } from '@vaadin/a11y-base/src/focus-mixin.js';
10
9
  import { KeyboardMixin } from '@vaadin/a11y-base/src/keyboard-mixin.js';
11
10
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
11
+ import { SlotObserver } from '@vaadin/component-base/src/slot-observer.js';
12
12
  import { TooltipController } from '@vaadin/component-base/src/tooltip-controller.js';
13
13
  import { generateUniqueId } from '@vaadin/component-base/src/unique-id-utils.js';
14
14
  import { FieldMixin } from '@vaadin/field-base/src/field-mixin.js';
@@ -95,6 +95,11 @@ class RadioGroup extends FieldMixin(
95
95
  width: 100%;
96
96
  }
97
97
 
98
+ [part='group-field'] {
99
+ display: flex;
100
+ flex-wrap: wrap;
101
+ }
102
+
98
103
  :host(:not([has-label])) [part='label'] {
99
104
  display: none;
100
105
  }
@@ -158,6 +163,19 @@ class RadioGroup extends FieldMixin(
158
163
  _fieldName: {
159
164
  type: String,
160
165
  },
166
+
167
+ /**
168
+ * Whether the field is dirty.
169
+ *
170
+ * The field is automatically marked as dirty once the user triggers
171
+ * a `change` event. Additionally, the field can be manually marked
172
+ * as dirty by setting the property to `true`.
173
+ */
174
+ dirty: {
175
+ type: Boolean,
176
+ value: false,
177
+ notify: true,
178
+ },
161
179
  };
162
180
  }
163
181
 
@@ -166,6 +184,7 @@ class RadioGroup extends FieldMixin(
166
184
 
167
185
  this.__registerRadioButton = this.__registerRadioButton.bind(this);
168
186
  this.__unregisterRadioButton = this.__unregisterRadioButton.bind(this);
187
+ this.__onRadioButtonChange = this.__onRadioButtonChange.bind(this);
169
188
  this.__onRadioButtonCheckedChange = this.__onRadioButtonCheckedChange.bind(this);
170
189
  }
171
190
 
@@ -208,7 +227,8 @@ class RadioGroup extends FieldMixin(
208
227
 
209
228
  this._fieldName = `${this.localName}-${generateUniqueId()}`;
210
229
 
211
- this._observer = new FlattenedNodesObserver(this, ({ addedNodes, removedNodes }) => {
230
+ const slot = this.shadowRoot.querySelector('slot:not([name])');
231
+ this._observer = new SlotObserver(slot, ({ addedNodes, removedNodes }) => {
212
232
  // Registers the added radio buttons in the reverse order
213
233
  // in order for the group to take the value of the most recent button.
214
234
  this.__filterRadioButtons(addedNodes).reverse().forEach(this.__registerRadioButton);
@@ -317,6 +337,7 @@ class RadioGroup extends FieldMixin(
317
337
  */
318
338
  __registerRadioButton(radioButton) {
319
339
  radioButton.name = this._fieldName;
340
+ radioButton.addEventListener('change', this.__onRadioButtonChange);
320
341
  radioButton.addEventListener('checked-changed', this.__onRadioButtonCheckedChange);
321
342
 
322
343
  if (this.disabled || this.readonly) {
@@ -335,6 +356,7 @@ class RadioGroup extends FieldMixin(
335
356
  * @private
336
357
  */
337
358
  __unregisterRadioButton(radioButton) {
359
+ radioButton.removeEventListener('change', this.__onRadioButtonChange);
338
360
  radioButton.removeEventListener('checked-changed', this.__onRadioButtonCheckedChange);
339
361
 
340
362
  if (radioButton.value === this.value) {
@@ -342,6 +364,11 @@ class RadioGroup extends FieldMixin(
342
364
  }
343
365
  }
344
366
 
367
+ /** @private */
368
+ __onRadioButtonChange() {
369
+ this.dirty = true;
370
+ }
371
+
345
372
  /**
346
373
  * @param {!CustomEvent} event
347
374
  * @private
@@ -459,7 +486,9 @@ class RadioGroup extends FieldMixin(
459
486
  _setFocused(focused) {
460
487
  super._setFocused(focused);
461
488
 
462
- if (!focused) {
489
+ // Do not validate when focusout is caused by document
490
+ // losing focus, which happens on browser tab switch.
491
+ if (!focused && document.hasFocus()) {
463
492
  this.validate();
464
493
  }
465
494
  }
@@ -27,7 +27,6 @@ const radioGroup = css`
27
27
  }
28
28
 
29
29
  :host([theme~='vertical']) [part='group-field'] {
30
- display: flex;
31
30
  flex-direction: column;
32
31
  }
33
32
 
@@ -27,7 +27,6 @@ const radioGroup = css`
27
27
  }
28
28
 
29
29
  :host([theme~='vertical']) [part='group-field'] {
30
- display: flex;
31
30
  flex-direction: column;
32
31
  }
33
32
 
package/web-types.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/radio-group",
4
- "version": "24.2.0-alpha1",
4
+ "version": "24.2.0-alpha10",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
@@ -32,6 +32,17 @@
32
32
  ]
33
33
  }
34
34
  },
35
+ {
36
+ "name": "dirty",
37
+ "description": "Whether the field is dirty.\n\nThe field is automatically marked as dirty once the user triggers\nan `input` or `change` event. Additionally, the field can be manually\nmarked as dirty by setting the property to `true`.",
38
+ "value": {
39
+ "type": [
40
+ "boolean",
41
+ "null",
42
+ "undefined"
43
+ ]
44
+ }
45
+ },
35
46
  {
36
47
  "name": "checked",
37
48
  "description": "True if the element is checked.",
@@ -97,6 +108,17 @@
97
108
  ]
98
109
  }
99
110
  },
111
+ {
112
+ "name": "dirty",
113
+ "description": "Whether the field is dirty.\n\nThe field is automatically marked as dirty once the user triggers\nan `input` or `change` event. Additionally, the field can be manually\nmarked as dirty by setting the property to `true`.",
114
+ "value": {
115
+ "type": [
116
+ "boolean",
117
+ "null",
118
+ "undefined"
119
+ ]
120
+ }
121
+ },
100
122
  {
101
123
  "name": "checked",
102
124
  "description": "True if the element is checked.",
@@ -132,6 +154,10 @@
132
154
  "name": "value-changed",
133
155
  "description": "Fired when the `value` property changes."
134
156
  },
157
+ {
158
+ "name": "dirty-changed",
159
+ "description": "Fired when the `dirty` property changes."
160
+ },
135
161
  {
136
162
  "name": "checked-changed",
137
163
  "description": "Fired when the `checked` property changes."
@@ -249,6 +275,17 @@
249
275
  ]
250
276
  }
251
277
  },
278
+ {
279
+ "name": "dirty",
280
+ "description": "Whether the field is dirty.\n\nThe field is automatically marked as dirty once the user triggers\na `change` event. Additionally, the field can be manually marked\nas dirty by setting the property to `true`.",
281
+ "value": {
282
+ "type": [
283
+ "boolean",
284
+ "null",
285
+ "undefined"
286
+ ]
287
+ }
288
+ },
252
289
  {
253
290
  "name": "theme",
254
291
  "description": "The theme variants to apply to the component.",
@@ -368,6 +405,17 @@
368
405
  "boolean"
369
406
  ]
370
407
  }
408
+ },
409
+ {
410
+ "name": "dirty",
411
+ "description": "Whether the field is dirty.\n\nThe field is automatically marked as dirty once the user triggers\na `change` event. Additionally, the field can be manually marked\nas dirty by setting the property to `true`.",
412
+ "value": {
413
+ "type": [
414
+ "boolean",
415
+ "null",
416
+ "undefined"
417
+ ]
418
+ }
371
419
  }
372
420
  ],
373
421
  "events": [
@@ -379,6 +427,10 @@
379
427
  "name": "value-changed",
380
428
  "description": "Fired when the `value` property changes."
381
429
  },
430
+ {
431
+ "name": "dirty-changed",
432
+ "description": "Fired when the `dirty` property changes."
433
+ },
382
434
  {
383
435
  "name": "invalid-changed",
384
436
  "description": "Fired when the `invalid` property changes."
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/radio-group",
4
- "version": "24.2.0-alpha1",
4
+ "version": "24.2.0-alpha10",
5
5
  "description-markup": "markdown",
6
6
  "framework": "lit",
7
7
  "framework-config": {
@@ -26,6 +26,13 @@
26
26
  "kind": "expression"
27
27
  }
28
28
  },
29
+ {
30
+ "name": "?dirty",
31
+ "description": "Whether the field is dirty.\n\nThe field is automatically marked as dirty once the user triggers\nan `input` or `change` event. Additionally, the field can be manually\nmarked as dirty by setting the property to `true`.",
32
+ "value": {
33
+ "kind": "expression"
34
+ }
35
+ },
29
36
  {
30
37
  "name": "?checked",
31
38
  "description": "True if the element is checked.",
@@ -61,6 +68,13 @@
61
68
  "kind": "expression"
62
69
  }
63
70
  },
71
+ {
72
+ "name": "@dirty-changed",
73
+ "description": "Fired when the `dirty` property changes.",
74
+ "value": {
75
+ "kind": "expression"
76
+ }
77
+ },
64
78
  {
65
79
  "name": "@checked-changed",
66
80
  "description": "Fired when the `checked` property changes.",
@@ -103,6 +117,13 @@
103
117
  "kind": "expression"
104
118
  }
105
119
  },
120
+ {
121
+ "name": "?dirty",
122
+ "description": "Whether the field is dirty.\n\nThe field is automatically marked as dirty once the user triggers\na `change` event. Additionally, the field can be manually marked\nas dirty by setting the property to `true`.",
123
+ "value": {
124
+ "kind": "expression"
125
+ }
126
+ },
106
127
  {
107
128
  "name": ".label",
108
129
  "description": "The label text for the input node.\nWhen no light dom defined via [slot=label], this value will be used.",
@@ -159,6 +180,13 @@
159
180
  "kind": "expression"
160
181
  }
161
182
  },
183
+ {
184
+ "name": "@dirty-changed",
185
+ "description": "Fired when the `dirty` property changes.",
186
+ "value": {
187
+ "kind": "expression"
188
+ }
189
+ },
162
190
  {
163
191
  "name": "@invalid-changed",
164
192
  "description": "Fired when the `invalid` property changes.",