@vaadin/checkbox 22.0.0-alpha6 → 22.0.0-beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,10 +1,29 @@
1
1
  {
2
2
  "name": "@vaadin/checkbox",
3
- "version": "22.0.0-alpha6",
3
+ "version": "22.0.0-beta1",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
4
7
  "description": "vaadin-checkbox",
8
+ "license": "Apache-2.0",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/vaadin/web-components.git",
12
+ "directory": "packages/checkbox"
13
+ },
14
+ "author": "Vaadin Ltd",
15
+ "homepage": "https://vaadin.com/components",
16
+ "bugs": {
17
+ "url": "https://github.com/vaadin/web-components/issues"
18
+ },
5
19
  "main": "vaadin-checkbox.js",
6
20
  "module": "vaadin-checkbox.js",
7
- "repository": "vaadin/web-components",
21
+ "files": [
22
+ "src",
23
+ "theme",
24
+ "vaadin-*.d.ts",
25
+ "vaadin-*.js"
26
+ ],
8
27
  "keywords": [
9
28
  "Vaadin",
10
29
  "checkbox",
@@ -12,33 +31,18 @@
12
31
  "web-component",
13
32
  "polymer"
14
33
  ],
15
- "author": "Vaadin Ltd",
16
- "license": "Apache-2.0",
17
- "bugs": {
18
- "url": "https://github.com/vaadin/web-components/issues"
19
- },
20
- "homepage": "https://vaadin.com/components",
21
- "files": [
22
- "vaadin-*.d.ts",
23
- "vaadin-*.js",
24
- "src",
25
- "theme"
26
- ],
27
34
  "dependencies": {
28
35
  "@polymer/polymer": "^3.0.0",
29
- "@vaadin/vaadin-control-state-mixin": "^22.0.0-alpha6",
30
- "@vaadin/vaadin-element-mixin": "^22.0.0-alpha6",
31
- "@vaadin/vaadin-lumo-styles": "^22.0.0-alpha6",
32
- "@vaadin/vaadin-material-styles": "^22.0.0-alpha6",
33
- "@vaadin/vaadin-themable-mixin": "^22.0.0-alpha6"
36
+ "@vaadin/component-base": "22.0.0-beta1",
37
+ "@vaadin/field-base": "22.0.0-beta1",
38
+ "@vaadin/vaadin-lumo-styles": "22.0.0-beta1",
39
+ "@vaadin/vaadin-material-styles": "22.0.0-beta1",
40
+ "@vaadin/vaadin-themable-mixin": "22.0.0-beta1"
34
41
  },
35
42
  "devDependencies": {
36
43
  "@esm-bundle/chai": "^4.3.4",
37
44
  "@vaadin/testing-helpers": "^0.3.0",
38
45
  "sinon": "^9.2.0"
39
46
  },
40
- "publishConfig": {
41
- "access": "public"
42
- },
43
- "gitHead": "4b136b1c7da8942960e7255f40c27859125b3a45"
47
+ "gitHead": "4cf8a9d0504994200c610e44b3676114fef49c1e"
44
48
  }
@@ -1,11 +1,15 @@
1
- import { GestureEventListeners } from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
2
-
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2021 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { ActiveMixin } from '@vaadin/component-base/src/active-mixin.js';
7
+ import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
8
+ import { CheckedMixin } from '@vaadin/field-base/src/checked-mixin.js';
9
+ import { DelegateFocusMixin } from '@vaadin/field-base/src/delegate-focus-mixin.js';
10
+ import { SlotLabelMixin } from '@vaadin/field-base/src/slot-label-mixin.js';
3
11
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
4
12
 
5
- import { ControlStateMixin } from '@vaadin/vaadin-control-state-mixin/vaadin-control-state-mixin.js';
6
-
7
- import { ElementMixin } from '@vaadin/vaadin-element-mixin/vaadin-element-mixin.js';
8
-
9
13
  /**
10
14
  * Fired when the `checked` property changes.
11
15
  */
@@ -16,95 +20,80 @@ export type CheckboxCheckedChangedEvent = CustomEvent<{ value: boolean }>;
16
20
  */
17
21
  export type CheckboxIndeterminateChangedEvent = CustomEvent<{ value: boolean }>;
18
22
 
19
- export interface CheckboxElementEventMap {
23
+ export interface CheckboxCustomEventMap {
20
24
  'checked-changed': CheckboxCheckedChangedEvent;
21
25
 
22
26
  'indeterminate-changed': CheckboxIndeterminateChangedEvent;
23
27
  }
24
28
 
25
- export interface CheckboxEventMap extends HTMLElementEventMap, CheckboxElementEventMap {}
29
+ export interface CheckboxEventMap extends HTMLElementEventMap, CheckboxCustomEventMap {}
26
30
 
27
31
  /**
28
- * `<vaadin-checkbox>` is a Web Component for customized checkboxes.
32
+ * `<vaadin-checkbox>` is an input field representing a binary choice.
29
33
  *
30
34
  * ```html
31
- * <vaadin-checkbox>
32
- * Make my profile visible
33
- * </vaadin-checkbox>
35
+ * <vaadin-checkbox label="I accept the terms and conditions"></vaadin-checkbox>
34
36
  * ```
35
37
  *
36
38
  * ### Styling
37
39
  *
38
40
  * The following shadow DOM parts are available for styling:
39
41
  *
40
- * Part name | Description
41
- * ------------------|----------------
42
- * `checkbox` | The wrapper element for the native <input type="checkbox">
43
- * `label` | The wrapper element in which the component's children, namely the label, is slotted
42
+ * Part name | Description
43
+ * ------------|----------------
44
+ * `checkbox` | The wrapper element that contains slotted `<input type="checkbox">`
44
45
  *
45
46
  * The following state attributes are available for styling:
46
47
  *
47
- * Attribute | Description | Part name
48
- * -------------|-------------|--------------
49
- * `active` | Set when the checkbox is pressed down, either with mouse, touch or the keyboard. | `:host`
50
- * `disabled` | Set when the checkbox is disabled. | `:host`
51
- * `focus-ring` | Set when the checkbox is focused using the keyboard. | `:host`
52
- * `focused` | Set when the checkbox is focused. | `:host`
53
- * `indeterminate` | Set when the checkbox is in indeterminate mode. | `:host`
54
- * `checked` | Set when the checkbox is checked. | `:host`
55
- * `empty` | Set when there is no label provided. | `label`
48
+ * Attribute | Description | Part name
49
+ * ----------------|-------------|--------------
50
+ * `active` | Set when the checkbox is pressed down, either with mouse, touch or the keyboard. | `:host`
51
+ * `disabled` | Set when the checkbox is disabled. | `:host`
52
+ * `focus-ring` | Set when the checkbox is focused using the keyboard. | `:host`
53
+ * `focused` | Set when the checkbox is focused. | `:host`
54
+ * `indeterminate` | Set when the checkbox is in the indeterminate state. | `:host`
55
+ * `checked` | Set when the checkbox is checked. | `:host`
56
+ * `has-label` | Set when the checkbox has a label. | `:host`
56
57
  *
57
58
  * See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
58
59
  *
59
- * @fires {Event} change - Fired when the user commits a value change.
60
60
  * @fires {CustomEvent} checked-changed - Fired when the `checked` property changes.
61
61
  * @fires {CustomEvent} indeterminate-changed - Fired when the `indeterminate` property changes.
62
62
  */
63
- declare class CheckboxElement extends ElementMixin(
64
- ControlStateMixin(ThemableMixin(GestureEventListeners(HTMLElement)))
63
+ declare class Checkbox extends SlotLabelMixin(
64
+ CheckedMixin(DelegateFocusMixin(ActiveMixin(ElementMixin(ThemableMixin(HTMLElement)))))
65
65
  ) {
66
- readonly focusElement: HTMLInputElement;
67
-
68
66
  /**
69
- * Name of the element.
70
- */
71
- name: string;
72
-
73
- /**
74
- * True if the checkbox is checked.
75
- */
76
- checked: boolean;
77
-
78
- /**
79
- * Indeterminate state of the checkbox when it's neither checked nor unchecked, but undetermined.
67
+ * True if the checkbox is in the indeterminate state which means
68
+ * it is not possible to say whether it is checked or unchecked.
69
+ * The state is reset once the user switches the checkbox by hand.
70
+ *
80
71
  * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#Indeterminate_state_checkboxes
81
72
  */
82
73
  indeterminate: boolean;
83
74
 
84
75
  /**
85
- * The value given to the data submitted with the checkbox's name to the server when the control is inside a form.
76
+ * The name of the checkbox.
86
77
  */
87
- value: string | null | undefined;
88
-
89
- _toggleChecked(): void;
78
+ name: string;
90
79
 
91
80
  addEventListener<K extends keyof CheckboxEventMap>(
92
81
  type: K,
93
- listener: (this: CheckboxElement, ev: CheckboxEventMap[K]) => void,
82
+ listener: (this: Checkbox, ev: CheckboxEventMap[K]) => void,
94
83
  options?: boolean | AddEventListenerOptions
95
84
  ): void;
96
85
 
97
86
  removeEventListener<K extends keyof CheckboxEventMap>(
98
87
  type: K,
99
- listener: (this: CheckboxElement, ev: CheckboxEventMap[K]) => void,
88
+ listener: (this: Checkbox, ev: CheckboxEventMap[K]) => void,
100
89
  options?: boolean | EventListenerOptions
101
90
  ): void;
102
91
  }
103
92
 
104
93
  declare global {
105
94
  interface HTMLElementTagNameMap {
106
- 'vaadin-checkbox': CheckboxElement;
95
+ 'vaadin-checkbox': Checkbox;
107
96
  }
108
97
  }
109
98
 
110
- export { CheckboxElement };
99
+ export { Checkbox };
@@ -4,54 +4,62 @@
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
7
- import { GestureEventListeners } from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
7
+ import { ActiveMixin } from '@vaadin/component-base/src/active-mixin.js';
8
+ import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
9
+ import { AriaLabelController } from '@vaadin/field-base/src/aria-label-controller.js';
10
+ import { CheckedMixin } from '@vaadin/field-base/src/checked-mixin.js';
11
+ import { DelegateFocusMixin } from '@vaadin/field-base/src/delegate-focus-mixin.js';
12
+ import { InputController } from '@vaadin/field-base/src/input-controller.js';
13
+ import { SlotLabelMixin } from '@vaadin/field-base/src/slot-label-mixin.js';
8
14
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
9
- import { ControlStateMixin } from '@vaadin/vaadin-control-state-mixin/vaadin-control-state-mixin.js';
10
- import { ElementMixin } from '@vaadin/vaadin-element-mixin/vaadin-element-mixin.js';
11
15
 
12
16
  /**
13
- * `<vaadin-checkbox>` is a Web Component for customized checkboxes.
17
+ * `<vaadin-checkbox>` is an input field representing a binary choice.
14
18
  *
15
19
  * ```html
16
- * <vaadin-checkbox>
17
- * Make my profile visible
18
- * </vaadin-checkbox>
20
+ * <vaadin-checkbox label="I accept the terms and conditions"></vaadin-checkbox>
19
21
  * ```
20
22
  *
21
23
  * ### Styling
22
24
  *
23
25
  * The following shadow DOM parts are available for styling:
24
26
  *
25
- * Part name | Description
26
- * ------------------|----------------
27
- * `checkbox` | The wrapper element for the native <input type="checkbox">
28
- * `label` | The wrapper element in which the component's children, namely the label, is slotted
27
+ * Part name | Description
28
+ * ------------|----------------
29
+ * `checkbox` | The wrapper element that contains slotted <input type="checkbox">.
29
30
  *
30
31
  * The following state attributes are available for styling:
31
32
  *
32
- * Attribute | Description | Part name
33
- * -------------|-------------|--------------
34
- * `active` | Set when the checkbox is pressed down, either with mouse, touch or the keyboard. | `:host`
35
- * `disabled` | Set when the checkbox is disabled. | `:host`
36
- * `focus-ring` | Set when the checkbox is focused using the keyboard. | `:host`
37
- * `focused` | Set when the checkbox is focused. | `:host`
38
- * `indeterminate` | Set when the checkbox is in indeterminate mode. | `:host`
39
- * `checked` | Set when the checkbox is checked. | `:host`
40
- * `empty` | Set when there is no label provided. | `label`
33
+ * Attribute | Description | Part name
34
+ * ----------------|-------------|--------------
35
+ * `active` | Set when the checkbox is pressed down, either with mouse, touch or the keyboard. | `:host`
36
+ * `disabled` | Set when the checkbox is disabled. | `:host`
37
+ * `focus-ring` | Set when the checkbox is focused using the keyboard. | `:host`
38
+ * `focused` | Set when the checkbox is focused. | `:host`
39
+ * `indeterminate` | Set when the checkbox is in the indeterminate state. | `:host`
40
+ * `checked` | Set when the checkbox is checked. | `:host`
41
+ * `has-label` | Set when the checkbox has a label. | `:host`
41
42
  *
42
43
  * See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
43
44
  *
44
- * @fires {Event} change - Fired when the user commits a value change.
45
45
  * @fires {CustomEvent} checked-changed - Fired when the `checked` property changes.
46
46
  * @fires {CustomEvent} indeterminate-changed - Fired when the `indeterminate` property changes.
47
47
  *
48
48
  * @extends HTMLElement
49
- * @mixes ElementMixin
50
- * @mixes ControlStateMixin
51
49
  * @mixes ThemableMixin
52
- * @mixes GestureEventListeners
50
+ * @mixes ElementMixin
51
+ * @mixes ActiveMixin
52
+ * @mixes DelegateFocusMixin
53
+ * @mixes CheckedMixin
54
+ * @mixes SlotLabelMixin
53
55
  */
54
- class CheckboxElement extends ElementMixin(ControlStateMixin(ThemableMixin(GestureEventListeners(PolymerElement)))) {
56
+ class Checkbox extends SlotLabelMixin(
57
+ CheckedMixin(DelegateFocusMixin(ActiveMixin(ElementMixin(ThemableMixin(PolymerElement)))))
58
+ ) {
59
+ static get is() {
60
+ return 'vaadin-checkbox';
61
+ }
62
+
55
63
  static get template() {
56
64
  return html`
57
65
  <style>
@@ -63,19 +71,22 @@ class CheckboxElement extends ElementMixin(ControlStateMixin(ThemableMixin(Gestu
63
71
  display: none !important;
64
72
  }
65
73
 
66
- label {
74
+ :host([disabled]) {
75
+ -webkit-tap-highlight-color: transparent;
76
+ }
77
+
78
+ .vaadin-checkbox-container {
67
79
  display: inline-flex;
68
80
  align-items: baseline;
69
- outline: none;
70
81
  }
71
82
 
72
- [part='checkbox'] {
83
+ .vaadin-checkbox-wrapper {
73
84
  position: relative;
74
- display: inline-block;
75
85
  flex: none;
76
86
  }
77
87
 
78
- input[type='checkbox'] {
88
+ /* visually hidden */
89
+ ::slotted(input) {
79
90
  position: absolute;
80
91
  top: 0;
81
92
  left: 0;
@@ -86,248 +97,146 @@ class CheckboxElement extends ElementMixin(ControlStateMixin(ThemableMixin(Gestu
86
97
  cursor: inherit;
87
98
  margin: 0;
88
99
  }
89
-
90
- :host([disabled]) {
91
- -webkit-tap-highlight-color: transparent;
92
- }
93
100
  </style>
94
-
95
- <label>
96
- <span part="checkbox">
97
- <input
98
- type="checkbox"
99
- checked="{{checked::change}}"
100
- disabled$="[[disabled]]"
101
- indeterminate="{{indeterminate::change}}"
102
- role="presentation"
103
- tabindex="-1"
104
- />
105
- </span>
106
-
107
- <span part="label">
108
- <slot></slot>
109
- </span>
110
- </label>
101
+ <div class="vaadin-checkbox-container">
102
+ <div class="vaadin-checkbox-wrapper">
103
+ <div part="checkbox"></div>
104
+ <slot name="input"></slot>
105
+ </div>
106
+
107
+ <slot name="label"></slot>
108
+
109
+ <div style="display: none !important">
110
+ <slot id="noop"></slot>
111
+ </div>
112
+ </div>
111
113
  `;
112
114
  }
113
115
 
114
- static get is() {
115
- return 'vaadin-checkbox';
116
- }
117
-
118
116
  static get properties() {
119
117
  return {
120
118
  /**
121
- * True if the checkbox is checked.
122
- * @type {boolean}
123
- */
124
- checked: {
125
- type: Boolean,
126
- value: false,
127
- notify: true,
128
- observer: '_checkedChanged',
129
- reflectToAttribute: true
130
- },
131
-
132
- /**
133
- * Indeterminate state of the checkbox when it's neither checked nor unchecked, but undetermined.
119
+ * True if the checkbox is in the indeterminate state which means
120
+ * it is not possible to say whether it is checked or unchecked.
121
+ * The state is reset once the user switches the checkbox by hand.
122
+ *
134
123
  * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#Indeterminate_state_checkboxes
124
+ *
135
125
  * @type {boolean}
136
126
  */
137
127
  indeterminate: {
138
128
  type: Boolean,
139
129
  notify: true,
140
- observer: '_indeterminateChanged',
141
- reflectToAttribute: true,
142
- value: false
130
+ value: false,
131
+ reflectToAttribute: true
143
132
  },
144
133
 
145
134
  /**
146
- * The value given to the data submitted with the checkbox's name to the server when the control is inside a form.
135
+ * The name of the checkbox.
136
+ *
137
+ * @type {string}
147
138
  */
148
- value: {
139
+ name: {
149
140
  type: String,
150
- value: 'on'
151
- },
152
-
153
- /** @private */
154
- _nativeCheckbox: {
155
- type: Object
141
+ value: ''
156
142
  }
157
143
  };
158
144
  }
159
145
 
160
- constructor() {
161
- super();
162
- /**
163
- * @type {string}
164
- * Name of the element.
165
- */
166
- this.name;
167
- }
168
-
169
- get name() {
170
- return this.checked ? this._storedName : '';
146
+ /** @override */
147
+ static get delegateProps() {
148
+ return [...super.delegateProps, 'indeterminate'];
171
149
  }
172
150
 
173
- set name(name) {
174
- this._storedName = name;
151
+ /** @override */
152
+ static get delegateAttrs() {
153
+ return [...super.delegateAttrs, 'name'];
175
154
  }
176
155
 
177
- ready() {
178
- super.ready();
179
-
180
- this.setAttribute('role', 'checkbox');
181
-
182
- this._nativeCheckbox = this.shadowRoot.querySelector('input[type="checkbox"]');
183
-
184
- this.addEventListener('click', this._handleClick.bind(this));
185
-
186
- this._addActiveListeners();
187
-
188
- const attrName = this.getAttribute('name');
189
- if (attrName) {
190
- this.name = attrName;
191
- }
156
+ constructor() {
157
+ super();
192
158
 
193
- this.shadowRoot
194
- .querySelector('[part~="label"]')
195
- .querySelector('slot')
196
- .addEventListener('slotchange', this._updateLabelAttribute.bind(this));
159
+ this._setType('checkbox');
197
160
 
198
- this._updateLabelAttribute();
161
+ // Set the string "on" as the default value for the checkbox following the HTML specification:
162
+ // https://html.spec.whatwg.org/multipage/input.html#dom-input-value-default-on
163
+ this.value = 'on';
199
164
  }
200
165
 
201
- /** @private */
202
- _updateLabelAttribute() {
203
- const label = this.shadowRoot.querySelector('[part~="label"]');
204
- const assignedNodes = label.firstElementChild.assignedNodes();
205
- if (this._isAssignedNodesEmpty(assignedNodes)) {
206
- label.setAttribute('empty', '');
207
- } else {
208
- label.removeAttribute('empty');
209
- }
210
- }
166
+ /** @protected */
167
+ ready() {
168
+ super.ready();
211
169
 
212
- /** @private */
213
- _isAssignedNodesEmpty(nodes) {
214
- // The assigned nodes considered to be empty if there is no slotted content or only one empty text node
215
- return (
216
- nodes.length === 0 ||
217
- (nodes.length == 1 && nodes[0].nodeType == Node.TEXT_NODE && nodes[0].textContent.trim() === '')
170
+ this.addController(
171
+ new InputController(this, (input) => {
172
+ this._setInputElement(input);
173
+ this._setFocusElement(input);
174
+ this.stateTarget = input;
175
+ })
218
176
  );
177
+ this.addController(new AriaLabelController(this, this.inputElement, this._labelNode));
219
178
  }
220
179
 
221
- /** @private */
222
- _checkedChanged(checked) {
223
- if (this.indeterminate) {
224
- this.setAttribute('aria-checked', 'mixed');
225
- } else {
226
- this.setAttribute('aria-checked', Boolean(checked));
227
- }
228
- }
229
-
230
- /** @private */
231
- _indeterminateChanged(indeterminate) {
232
- if (indeterminate) {
233
- this.setAttribute('aria-checked', 'mixed');
234
- } else {
235
- this.setAttribute('aria-checked', this.checked);
236
- }
237
- }
238
-
239
- /** @private */
240
- _addActiveListeners() {
241
- // DOWN
242
- this._addEventListenerToNode(this, 'down', (e) => {
243
- if (this.__interactionsAllowed(e)) {
244
- this.setAttribute('active', '');
245
- }
246
- });
247
-
248
- // UP
249
- this._addEventListenerToNode(this, 'up', () => this.removeAttribute('active'));
250
-
251
- // KEYDOWN
252
- this.addEventListener('keydown', (e) => {
253
- if (this.__interactionsAllowed(e) && e.keyCode === 32) {
254
- e.preventDefault();
255
- this.setAttribute('active', '');
256
- }
257
- });
258
-
259
- // KEYUP
260
- this.addEventListener('keyup', (e) => {
261
- if (this.__interactionsAllowed(e) && e.keyCode === 32) {
262
- e.preventDefault();
263
- this._toggleChecked();
264
- this.removeAttribute('active');
265
-
266
- if (this.indeterminate) {
267
- this.indeterminate = false;
268
- }
269
- }
270
- });
180
+ /**
181
+ * A reference to the default slot from which nodes are copied to the label node.
182
+ *
183
+ * @override
184
+ * @protected
185
+ * @type {HTMLSlotElement}
186
+ */
187
+ get _sourceSlot() {
188
+ return this.$.noop;
271
189
  }
272
190
 
273
191
  /**
274
- * @return {!HTMLInputElement}
192
+ * Override __copyNodesToSlotTarget from SlotTargetMixin to show a warning.
193
+ * @override
275
194
  * @protected
276
- */
277
- get focusElement() {
278
- return this.shadowRoot.querySelector('input');
195
+ * @param {!Array<!Node>} nodes
196
+ **/
197
+ __copyNodesToSlotTarget(nodes) {
198
+ super.__copyNodesToSlotTarget(nodes);
199
+
200
+ console.warn(
201
+ `WARNING: Since Vaadin 22, placing the label as a direct child of a <vaadin-checkbox> is deprecated.
202
+ Please use <label slot="label"> wrapper or the label property instead.`
203
+ );
279
204
  }
280
205
 
281
206
  /**
282
- * True if users' interactions (mouse or keyboard)
283
- * should toggle the checkbox
207
+ * Extends the method from `ActiveMixin` in order to
208
+ * prevent setting the `active` attribute when interacting with a link inside the label.
209
+ *
210
+ * @param {Event} event
211
+ * @return {boolean}
212
+ * @protected
213
+ * @override
284
214
  */
285
- __interactionsAllowed(e) {
286
- if (this.disabled) {
287
- return false;
288
- }
289
-
290
- // https://github.com/vaadin/vaadin-checkbox/issues/63
291
- if (e.target.localName === 'a') {
215
+ _shouldSetActive(event) {
216
+ if (event.target.localName === 'a') {
292
217
  return false;
293
218
  }
294
219
 
295
- return true;
296
- }
297
-
298
- /** @private */
299
- _handleClick(e) {
300
- if (this.__interactionsAllowed(e)) {
301
- if (!this.indeterminate) {
302
- if (e.composedPath()[0] !== this._nativeCheckbox) {
303
- e.preventDefault();
304
- this._toggleChecked();
305
- }
306
- } else {
307
- /*
308
- * Required for IE 11 and Edge.
309
- * See issue here: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7344418/
310
- */
311
- this.indeterminate = false;
312
- e.preventDefault();
313
- this._toggleChecked();
314
- }
315
- }
316
- }
317
-
318
- /** @protected */
319
- _toggleChecked() {
320
- this.checked = !this.checked;
321
- this.dispatchEvent(new CustomEvent('change', { composed: false, bubbles: true }));
220
+ return super._shouldSetActive(event);
322
221
  }
323
222
 
324
223
  /**
325
- * Fired when the user commits a value change.
224
+ * Extends the method from `CheckedMixin` in order to
225
+ * reset the indeterminate state once the user switches the checkbox.
326
226
  *
327
- * @event change
227
+ * @param {boolean} checked
228
+ * @protected
229
+ * @override
328
230
  */
231
+ _toggleChecked(checked) {
232
+ if (this.indeterminate) {
233
+ this.indeterminate = false;
234
+ }
235
+
236
+ super._toggleChecked(checked);
237
+ }
329
238
  }
330
239
 
331
- customElements.define(CheckboxElement.is, CheckboxElement);
240
+ customElements.define(Checkbox.is, Checkbox);
332
241
 
333
- export { CheckboxElement };
242
+ export { Checkbox };
@@ -1,11 +1,20 @@
1
1
  import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
2
2
  import '@vaadin/vaadin-lumo-styles/color.js';
3
+ import '@vaadin/vaadin-lumo-styles/sizing.js';
4
+ import '@vaadin/vaadin-lumo-styles/spacing.js';
3
5
  import '@vaadin/vaadin-lumo-styles/style.js';
6
+ import '@vaadin/vaadin-lumo-styles/typography.js';
4
7
 
5
8
  registerStyles(
6
9
  'vaadin-checkbox',
7
10
  css`
8
11
  :host {
12
+ color: var(--lumo-body-text-color);
13
+ font-size: var(--lumo-font-size-m);
14
+ font-family: var(--lumo-font-family);
15
+ line-height: var(--lumo-line-height-s);
16
+ -webkit-font-smoothing: antialiased;
17
+ -moz-osx-font-smoothing: grayscale;
9
18
  -webkit-tap-highlight-color: transparent;
10
19
  -webkit-user-select: none;
11
20
  -moz-user-select: none;
@@ -14,21 +23,21 @@ registerStyles(
14
23
  outline: none;
15
24
  }
16
25
 
17
- [part='label']:not([empty]) {
18
- margin: 0.1875em 0.875em 0.1875em 0.375em;
26
+ :host([has-label]) ::slotted(label) {
27
+ padding: var(--lumo-space-xs) var(--lumo-space-s) var(--lumo-space-xs) var(--lumo-space-xs);
19
28
  }
20
29
 
21
30
  [part='checkbox'] {
22
- width: calc(1em + 2px);
23
- height: calc(1em + 2px);
24
- margin: 0.1875em;
31
+ width: calc(var(--lumo-size-m) / 2);
32
+ height: calc(var(--lumo-size-m) / 2);
33
+ margin: var(--lumo-space-xs);
25
34
  position: relative;
26
35
  border-radius: var(--lumo-border-radius-s);
27
36
  background-color: var(--lumo-contrast-20pct);
28
37
  transition: transform 0.2s cubic-bezier(0.12, 0.32, 0.54, 2), background-color 0.15s;
29
- pointer-events: none;
30
38
  line-height: 1.2;
31
39
  cursor: var(--lumo-clickable-cursor);
40
+ flex: none;
32
41
  }
33
42
 
34
43
  :host([indeterminate]) [part='checkbox'],
@@ -44,6 +53,7 @@ registerStyles(
44
53
  /* Checkmark */
45
54
  [part='checkbox']::after {
46
55
  content: '';
56
+ pointer-events: none;
47
57
  display: inline-block;
48
58
  width: 0;
49
59
  height: 0;
@@ -80,7 +90,7 @@ registerStyles(
80
90
 
81
91
  /* Focus ring */
82
92
  :host([focus-ring]) [part='checkbox'] {
83
- box-shadow: 0 0 0 3px var(--lumo-primary-color-50pct);
93
+ box-shadow: 0 0 0 1px var(--lumo-base-color), 0 0 0 3px var(--lumo-primary-color-50pct);
84
94
  }
85
95
 
86
96
  /* Disabled */
@@ -89,7 +99,7 @@ registerStyles(
89
99
  color: var(--lumo-disabled-text-color);
90
100
  }
91
101
 
92
- :host([disabled]) [part='label'] ::slotted(*) {
102
+ :host([disabled]) ::slotted(label) {
93
103
  color: inherit;
94
104
  }
95
105
 
@@ -106,8 +116,8 @@ registerStyles(
106
116
  }
107
117
 
108
118
  /* RTL specific styles */
109
- :host([dir='rtl']) [part='label']:not([empty]) {
110
- margin: 0.1875em 0.375em 0.1875em 0.875em;
119
+ :host([dir='rtl'][has-label]) ::slotted(label) {
120
+ padding: var(--lumo-space-xs) var(--lumo-space-xs) var(--lumo-space-xs) var(--lumo-space-s);
111
121
  }
112
122
 
113
123
  /* Transition the checkmark if activated with the mouse (disabled for grid select-all this way) */
@@ -117,6 +127,7 @@ registerStyles(
117
127
 
118
128
  /* Used for activation "halo" */
119
129
  [part='checkbox']::before {
130
+ pointer-events: none;
120
131
  color: transparent;
121
132
  display: inline-block;
122
133
  width: 100%;
@@ -14,25 +14,18 @@ registerStyles(
14
14
  -webkit-tap-highlight-color: transparent;
15
15
  }
16
16
 
17
- [part='label']:not([empty]) {
18
- margin: 3px 12px 3px 6px;
19
- }
20
-
21
- [part='native-checkbox'] {
22
- opacity: 0;
23
- position: absolute;
17
+ :host([has-label]) ::slotted(label) {
18
+ padding: 3px 12px 3px 6px;
24
19
  }
25
20
 
26
21
  [part='checkbox'] {
27
22
  display: inline-block;
28
23
  width: 16px;
29
24
  height: 16px;
30
- flex: none;
31
25
  margin: 4px;
32
26
  position: relative;
33
27
  border-radius: 2px;
34
28
  box-shadow: inset 0 0 0 2px var(--material-secondary-text-color);
35
- pointer-events: none;
36
29
  line-height: 1.275;
37
30
  background-color: transparent;
38
31
  }
@@ -41,6 +34,7 @@ registerStyles(
41
34
  [part='checkbox']::before {
42
35
  /* Needed to align the checkbox nicely on the baseline */
43
36
  content: '\\2003';
37
+ pointer-events: none;
44
38
  display: inline-block;
45
39
  width: 100%;
46
40
  height: 100%;
@@ -55,6 +49,7 @@ registerStyles(
55
49
  /* Used for the checkmark */
56
50
  [part='checkbox']::after {
57
51
  content: '';
52
+ pointer-events: none;
58
53
  display: inline-block;
59
54
  width: 10px;
60
55
  height: 19px;
@@ -113,7 +108,7 @@ registerStyles(
113
108
  color: var(--material-disabled-text-color);
114
109
  }
115
110
 
116
- :host([disabled]) ::slotted(*) {
111
+ :host([disabled]) ::slotted(label) {
117
112
  color: inherit;
118
113
  }
119
114
 
@@ -127,8 +122,8 @@ registerStyles(
127
122
  }
128
123
 
129
124
  /* RTL specific styles */
130
- :host([dir='rtl']) [part='label']:not([empty]) {
131
- margin: 3px 6px 3px 12px;
125
+ :host([dir='rtl'][has-label]) ::slotted(label) {
126
+ padding: 3px 6px 3px 12px;
132
127
  }
133
128
  `,
134
129
  { moduleId: 'material-checkbox' }