@vaadin/field-base 22.0.0-alpha6 → 22.0.0-alpha7

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 (63) hide show
  1. package/index.d.ts +6 -9
  2. package/index.js +6 -9
  3. package/package.json +22 -17
  4. package/src/aria-label-controller.d.ts +11 -0
  5. package/src/aria-label-controller.js +53 -0
  6. package/src/checked-mixin.js +37 -67
  7. package/src/delegate-focus-mixin.js +147 -131
  8. package/src/delegate-state-mixin.d.ts +1 -1
  9. package/src/delegate-state-mixin.js +100 -88
  10. package/src/field-mixin.d.ts +39 -0
  11. package/src/field-mixin.js +317 -0
  12. package/src/input-constraints-mixin.d.ts +4 -2
  13. package/src/input-constraints-mixin.js +105 -86
  14. package/src/input-control-mixin.d.ts +52 -0
  15. package/src/input-control-mixin.js +170 -0
  16. package/src/input-controller.d.ts +11 -0
  17. package/src/input-controller.js +35 -0
  18. package/src/input-field-mixin.d.ts +2 -16
  19. package/src/input-field-mixin.js +17 -89
  20. package/src/input-mixin.d.ts +1 -1
  21. package/src/input-mixin.js +156 -145
  22. package/src/label-mixin.d.ts +1 -1
  23. package/src/label-mixin.js +72 -59
  24. package/src/pattern-mixin.js +9 -9
  25. package/src/shadow-focus-mixin.d.ts +21 -0
  26. package/src/shadow-focus-mixin.js +87 -0
  27. package/src/slot-controller.d.ts +8 -0
  28. package/src/slot-controller.js +36 -0
  29. package/src/slot-label-mixin.d.ts +20 -0
  30. package/src/slot-label-mixin.js +38 -0
  31. package/src/slot-styles-mixin.js +38 -31
  32. package/src/slot-target-mixin.d.ts +8 -19
  33. package/src/slot-target-mixin.js +93 -73
  34. package/src/styles/clear-button-styles.d.ts +8 -0
  35. package/src/styles/clear-button-styles.js +21 -0
  36. package/src/styles/field-shared-styles.d.ts +8 -0
  37. package/src/styles/field-shared-styles.js +29 -0
  38. package/src/styles/input-field-container-styles.d.ts +8 -0
  39. package/src/styles/input-field-container-styles.js +16 -0
  40. package/src/styles/input-field-shared-styles.d.ts +8 -0
  41. package/src/styles/input-field-shared-styles.js +10 -0
  42. package/src/text-area-controller.d.ts +11 -0
  43. package/src/text-area-controller.js +38 -0
  44. package/src/validate-mixin.d.ts +1 -9
  45. package/src/validate-mixin.js +43 -120
  46. package/src/aria-label-mixin.d.ts +0 -20
  47. package/src/aria-label-mixin.js +0 -71
  48. package/src/char-length-mixin.d.ts +0 -30
  49. package/src/char-length-mixin.js +0 -42
  50. package/src/clear-button-mixin.d.ts +0 -28
  51. package/src/clear-button-mixin.js +0 -82
  52. package/src/delegate-input-state-mixin.d.ts +0 -43
  53. package/src/delegate-input-state-mixin.js +0 -63
  54. package/src/field-aria-mixin.d.ts +0 -24
  55. package/src/field-aria-mixin.js +0 -61
  56. package/src/helper-text-mixin.d.ts +0 -24
  57. package/src/helper-text-mixin.js +0 -144
  58. package/src/input-slot-mixin.d.ts +0 -26
  59. package/src/input-slot-mixin.js +0 -71
  60. package/src/text-area-slot-mixin.d.ts +0 -21
  61. package/src/text-area-slot-mixin.js +0 -56
  62. package/src/text-field-mixin.d.ts +0 -21
  63. package/src/text-field-mixin.js +0 -17
package/index.d.ts CHANGED
@@ -1,18 +1,15 @@
1
- export { AriaLabelMixin } from './src/aria-label-mixin.js';
2
- export { CharLengthMixin } from './src/char-length-mixin.js';
1
+ export { AriaLabelController } from './src/aria-label-controller.js';
3
2
  export { CheckedMixin } from './src/checked-mixin.js';
4
- export { ClearButtonMixin } from './src/clear-button-mixin.js';
5
3
  export { DelegateFocusMixin } from './src/delegate-focus-mixin.js';
6
- export { DelegateInputStateMixin } from './src/delegate-input-state-mixin.js';
7
4
  export { DelegateStateMixin } from './src/delegate-state-mixin.js';
8
- export { FieldAriaMixin } from './src/field-aria-mixin.js';
9
- export { HelperTextMixin } from './src/helper-text-mixin.js';
5
+ export { FieldMixin } from './src/field-mixin.js';
6
+ export { InputController } from './src/input-controller.js';
7
+ export { InputControlMixin } from './src/input-control-mixin.js';
10
8
  export { InputFieldMixin } from './src/input-field-mixin.js';
11
9
  export { InputMixin } from './src/input-mixin.js';
12
- export { InputSlotMixin } from './src/input-slot-mixin.js';
13
10
  export { LabelMixin } from './src/label-mixin.js';
14
11
  export { PatternMixin } from './src/pattern-mixin.js';
12
+ export { ShadowFocusMixin } from './src/shadow-focus-mixin.js';
15
13
  export { SlotStylesMixin } from './src/slot-styles-mixin.js';
16
- export { TextAreaSlotMixin } from './src/text-area-slot-mixin.js';
17
- export { TextFieldMixin } from './src/text-field-mixin.js';
14
+ export { TextAreaController } from './src/text-area-controller.js';
18
15
  export { ValidateMixin } from './src/validate-mixin.js';
package/index.js CHANGED
@@ -1,18 +1,15 @@
1
- export { AriaLabelMixin } from './src/aria-label-mixin.js';
2
- export { CharLengthMixin } from './src/char-length-mixin.js';
1
+ export { AriaLabelController } from './src/aria-label-controller.js';
3
2
  export { CheckedMixin } from './src/checked-mixin.js';
4
- export { ClearButtonMixin } from './src/clear-button-mixin.js';
5
3
  export { DelegateFocusMixin } from './src/delegate-focus-mixin.js';
6
- export { DelegateInputStateMixin } from './src/delegate-input-state-mixin.js';
7
4
  export { DelegateStateMixin } from './src/delegate-state-mixin.js';
8
- export { FieldAriaMixin } from './src/field-aria-mixin.js';
9
- export { HelperTextMixin } from './src/helper-text-mixin.js';
5
+ export { FieldMixin } from './src/field-mixin.js';
6
+ export { InputController } from './src/input-controller.js';
7
+ export { InputControlMixin } from './src/input-control-mixin.js';
10
8
  export { InputFieldMixin } from './src/input-field-mixin.js';
11
9
  export { InputMixin } from './src/input-mixin.js';
12
- export { InputSlotMixin } from './src/input-slot-mixin.js';
13
10
  export { LabelMixin } from './src/label-mixin.js';
14
11
  export { PatternMixin } from './src/pattern-mixin.js';
12
+ export { ShadowFocusMixin } from './src/shadow-focus-mixin.js';
15
13
  export { SlotStylesMixin } from './src/slot-styles-mixin.js';
16
- export { TextAreaSlotMixin } from './src/text-area-slot-mixin.js';
17
- export { TextFieldMixin } from './src/text-field-mixin.js';
14
+ export { TextAreaController } from './src/text-area-controller.js';
18
15
  export { ValidateMixin } from './src/validate-mixin.js';
package/package.json CHANGED
@@ -1,37 +1,42 @@
1
1
  {
2
2
  "name": "@vaadin/field-base",
3
- "version": "22.0.0-alpha6",
3
+ "version": "22.0.0-alpha7",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
4
7
  "description": "Vaadin field base mixins",
5
- "main": "index.js",
6
- "module": "index.js",
7
- "repository": "vaadin/web-components",
8
- "keywords": [
9
- "Vaadin",
10
- "web-components",
11
- "web-component"
12
- ],
13
- "author": "Vaadin Ltd",
14
8
  "license": "Apache-2.0",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/vaadin/web-components.git",
12
+ "directory": "packages/field-base"
13
+ },
14
+ "author": "Vaadin Ltd",
15
+ "homepage": "https://vaadin.com/components",
15
16
  "bugs": {
16
17
  "url": "https://github.com/vaadin/web-components"
17
18
  },
18
- "homepage": "https://vaadin.com/components",
19
+ "main": "index.js",
20
+ "module": "index.js",
19
21
  "files": [
20
- "index.js",
21
22
  "index.d.ts",
23
+ "index.js",
22
24
  "src"
23
25
  ],
26
+ "keywords": [
27
+ "Vaadin",
28
+ "web-components",
29
+ "web-component"
30
+ ],
24
31
  "dependencies": {
25
32
  "@polymer/polymer": "^3.0.0",
26
- "@vaadin/component-base": "^22.0.0-alpha6"
33
+ "@vaadin/component-base": "22.0.0-alpha7",
34
+ "lit": "^2.0.0"
27
35
  },
28
36
  "devDependencies": {
29
37
  "@esm-bundle/chai": "^4.3.4",
30
38
  "@vaadin/testing-helpers": "^0.3.0",
31
39
  "sinon": "^9.2.1"
32
40
  },
33
- "publishConfig": {
34
- "access": "public"
35
- },
36
- "gitHead": "4b136b1c7da8942960e7255f40c27859125b3a45"
41
+ "gitHead": "8e89419c6b44a1d225d5859e180d7b35e47ddb52"
37
42
  }
@@ -0,0 +1,11 @@
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 { ReactiveController } from 'lit';
7
+
8
+ /**
9
+ * A controller to link an input element with a slotted `<label>` element.
10
+ */
11
+ export class AriaLabelController implements ReactiveController {}
@@ -0,0 +1,53 @@
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
+
7
+ /**
8
+ * A controller to link an input element with a slotted `<label>` element.
9
+ */
10
+ export class AriaLabelController {
11
+ constructor(input, label) {
12
+ this.input = input;
13
+ this.label = label;
14
+ this.__preventDuplicateLabelClick = this.__preventDuplicateLabelClick.bind(this);
15
+ }
16
+
17
+ hostConnected() {
18
+ const label = this.label;
19
+ const input = this.input;
20
+
21
+ if (label) {
22
+ label.addEventListener('click', this.__preventDuplicateLabelClick);
23
+
24
+ if (input) {
25
+ input.setAttribute('aria-labelledby', label.id);
26
+ label.setAttribute('for', input.id);
27
+ }
28
+ }
29
+ }
30
+
31
+ hostDisconnected() {
32
+ const label = this.label;
33
+ if (label) {
34
+ label.removeEventListener('click', this.__preventDuplicateLabelClick);
35
+ }
36
+ }
37
+
38
+ /**
39
+ * The native platform fires an event for both the click on the label, and also
40
+ * the subsequent click on the native input element caused by label click.
41
+ * This results in two click events arriving at the host, but we only want one.
42
+ * This method prevents the duplicate click and ensures the correct isTrusted event
43
+ * with the correct event.target arrives at the host.
44
+ * @private
45
+ */
46
+ __preventDuplicateLabelClick() {
47
+ const inputClickHandler = (e) => {
48
+ e.stopImmediatePropagation();
49
+ this.input.removeEventListener('click', inputClickHandler);
50
+ };
51
+ this.input.addEventListener('click', inputClickHandler);
52
+ }
53
+ }
@@ -8,77 +8,47 @@ import { DisabledMixin } from '@vaadin/component-base/src/disabled-mixin.js';
8
8
  import { DelegateStateMixin } from './delegate-state-mixin.js';
9
9
  import { InputMixin } from './input-mixin.js';
10
10
 
11
- const CheckedMixinImplementation = (superclass) =>
12
- class CheckedMixinClass extends DelegateStateMixin(DisabledMixin(InputMixin(superclass))) {
13
- static get properties() {
14
- return {
15
- /**
16
- * True if the element is checked.
17
- * @type {boolean}
18
- */
19
- checked: {
20
- type: Boolean,
21
- value: false,
22
- notify: true,
23
- reflectToAttribute: true
24
- }
25
- };
26
- }
27
-
28
- static get delegateAttrs() {
29
- return [...super.delegateAttrs, 'checked'];
30
- }
31
-
32
- get _delegateStateTarget() {
33
- return this.inputElement;
34
- }
35
-
36
- /** @protected */
37
- ready() {
38
- super.ready();
39
-
40
- this.addEventListener('click', (event) => {
41
- this._onClick(event);
42
- });
43
- }
44
-
45
- /**
46
- * @param {!MouseEvent} event
47
- * @return {boolean}
48
- * @protected
49
- */
50
- _interactionsAllowed(event) {
51
- if (this.disabled) {
52
- return false;
11
+ /**
12
+ * A mixin to manage the checked state.
13
+ *
14
+ * @polymerMixin
15
+ * @mixes DelegateStateMixin
16
+ * @mixes DisabledMixin
17
+ * @mixes InputMixin
18
+ */
19
+ export const CheckedMixin = dedupingMixin(
20
+ (superclass) =>
21
+ class CheckedMixinClass extends DelegateStateMixin(DisabledMixin(InputMixin(superclass))) {
22
+ static get properties() {
23
+ return {
24
+ /**
25
+ * True if the element is checked.
26
+ * @type {boolean}
27
+ */
28
+ checked: {
29
+ type: Boolean,
30
+ value: false,
31
+ notify: true,
32
+ reflectToAttribute: true
33
+ }
34
+ };
53
35
  }
54
36
 
55
- if (event.target.localName === 'a') {
56
- return false;
37
+ static get delegateProps() {
38
+ return [...super.delegateProps, 'checked'];
57
39
  }
58
40
 
59
- return true;
60
- }
61
-
62
- /**
63
- * @param {!MouseEvent} event
64
- * @protected
65
- */
66
- _onClick(event) {
67
- if (!this._interactionsAllowed(event)) {
68
- event.preventDefault();
69
- return;
41
+ /**
42
+ * @protected
43
+ * @override
44
+ */
45
+ _onChange(event) {
46
+ this._toggleChecked(event.target.checked);
70
47
  }
71
48
 
72
- this._toggleChecked();
73
- }
74
-
75
- /** @protected */
76
- _toggleChecked() {
77
- this.checked = !this.checked;
49
+ /** @protected */
50
+ _toggleChecked(checked) {
51
+ this.checked = checked;
52
+ }
78
53
  }
79
- };
80
-
81
- /**
82
- * A mixin to manage the checked state.
83
- */
84
- export const CheckedMixin = dedupingMixin(CheckedMixinImplementation);
54
+ );
@@ -7,157 +7,173 @@ import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
7
7
  import { DisabledMixin } from '@vaadin/component-base/src/disabled-mixin.js';
8
8
  import { FocusMixin } from '@vaadin/component-base/src/focus-mixin.js';
9
9
 
10
- const DelegateFocusMixinImplementation = (superclass) =>
11
- class DelegateFocusMixinClass extends FocusMixin(DisabledMixin(superclass)) {
12
- static get properties() {
13
- return {
14
- /**
15
- * Specify that this control should have input focus when the page loads.
16
- */
17
- autofocus: {
18
- type: Boolean
19
- },
20
-
21
- /**
22
- * A reference to the focusable element controlled by the mixin.
23
- * It can be an input, textarea, button or any element with tabindex > -1.
24
- *
25
- * Any component implementing this mixin is expected to provide it
26
- * by using `this._setFocusElement(input)` Polymer API.
27
- *
28
- * @protected
29
- * @type {!HTMLElement}
30
- */
31
- focusElement: {
32
- type: Object,
33
- readOnly: true,
34
- observer: '_focusElementChanged'
35
- }
36
- };
37
- }
10
+ /**
11
+ * A mixin to forward focus to an element in the light DOM.
12
+ *
13
+ * @polymerMixin
14
+ * @mixes DisabledMixin
15
+ * @mixes FocusMixin
16
+ */
17
+ export const DelegateFocusMixin = dedupingMixin(
18
+ (superclass) =>
19
+ class DelegateFocusMixinClass extends FocusMixin(DisabledMixin(superclass)) {
20
+ static get properties() {
21
+ return {
22
+ /**
23
+ * Specify that this control should have input focus when the page loads.
24
+ */
25
+ autofocus: {
26
+ type: Boolean
27
+ },
28
+
29
+ /**
30
+ * A reference to the focusable element controlled by the mixin.
31
+ * It can be an input, textarea, button or any element with tabindex > -1.
32
+ *
33
+ * Any component implementing this mixin is expected to provide it
34
+ * by using `this._setFocusElement(input)` Polymer API.
35
+ *
36
+ * @protected
37
+ * @type {!HTMLElement}
38
+ */
39
+ focusElement: {
40
+ type: Object,
41
+ readOnly: true,
42
+ observer: '_focusElementChanged'
43
+ }
44
+ };
45
+ }
38
46
 
39
- constructor() {
40
- super();
47
+ constructor() {
48
+ super();
41
49
 
42
- this._boundOnBlur = this._onBlur.bind(this);
43
- this._boundOnFocus = this._onFocus.bind(this);
44
- }
50
+ this._boundOnBlur = this._onBlur.bind(this);
51
+ this._boundOnFocus = this._onFocus.bind(this);
52
+ }
45
53
 
46
- /** @protected */
47
- ready() {
48
- super.ready();
54
+ /** @protected */
55
+ ready() {
56
+ super.ready();
49
57
 
50
- if (this.autofocus && !this.disabled) {
51
- requestAnimationFrame(() => {
52
- this.focus();
53
- this.setAttribute('focus-ring', '');
54
- });
58
+ if (this.autofocus && !this.disabled) {
59
+ requestAnimationFrame(() => {
60
+ this.focus();
61
+ this.setAttribute('focus-ring', '');
62
+ });
63
+ }
55
64
  }
56
- }
57
65
 
58
- focus() {
59
- if (!this.focusElement || this.disabled) {
60
- return;
61
- }
66
+ /**
67
+ * @protected
68
+ * @override
69
+ */
70
+ focus() {
71
+ if (!this.focusElement || this.disabled) {
72
+ return;
73
+ }
62
74
 
63
- this.focusElement.focus();
64
- this._setFocused(true);
65
- }
75
+ this.focusElement.focus();
76
+ this._setFocused(true);
77
+ }
66
78
 
67
- blur() {
68
- if (!this.focusElement) {
69
- return;
79
+ /**
80
+ * @protected
81
+ * @override
82
+ */
83
+ blur() {
84
+ if (!this.focusElement) {
85
+ return;
86
+ }
87
+ this.focusElement.blur();
88
+ this._setFocused(false);
70
89
  }
71
- this.focusElement.blur();
72
- this._setFocused(false);
73
- }
74
90
 
75
- click() {
76
- if (this.focusElement && !this.disabled) {
77
- this.focusElement.click();
91
+ /**
92
+ * @protected
93
+ * @override
94
+ */
95
+ click() {
96
+ if (this.focusElement && !this.disabled) {
97
+ this.focusElement.click();
98
+ }
78
99
  }
79
- }
80
100
 
81
- /** @protected */
82
- _focusElementChanged(element, oldElement) {
83
- if (element) {
84
- element.disabled = this.disabled;
85
- this._addFocusListeners(element);
86
- } else if (oldElement) {
87
- this._removeFocusListeners(oldElement);
101
+ /** @protected */
102
+ _focusElementChanged(element, oldElement) {
103
+ if (element) {
104
+ element.disabled = this.disabled;
105
+ this._addFocusListeners(element);
106
+ } else if (oldElement) {
107
+ this._removeFocusListeners(oldElement);
108
+ }
88
109
  }
89
- }
90
110
 
91
- /**
92
- * @param {HTMLElement} element
93
- * @protected
94
- */
95
- _addFocusListeners(element) {
96
- element.addEventListener('blur', this._boundOnBlur);
97
- element.addEventListener('focus', this._boundOnFocus);
98
- }
111
+ /**
112
+ * @param {HTMLElement} element
113
+ * @protected
114
+ */
115
+ _addFocusListeners(element) {
116
+ element.addEventListener('blur', this._boundOnBlur);
117
+ element.addEventListener('focus', this._boundOnFocus);
118
+ }
99
119
 
100
- /**
101
- * @param {HTMLElement} element
102
- * @protected
103
- */
104
- _removeFocusListeners(element) {
105
- element.removeEventListener('blur', this._boundOnBlur);
106
- element.removeEventListener('focus', this._boundOnFocus);
107
- }
120
+ /**
121
+ * @param {HTMLElement} element
122
+ * @protected
123
+ */
124
+ _removeFocusListeners(element) {
125
+ element.removeEventListener('blur', this._boundOnBlur);
126
+ element.removeEventListener('focus', this._boundOnFocus);
127
+ }
108
128
 
109
- /**
110
- * Focus event does not bubble, so we dispatch it manually
111
- * on the host element to support adding focus listeners
112
- * when the focusable element is placed in light DOM.
113
- * @param {FocusEvent} event
114
- * @protected
115
- */
116
- _onFocus(event) {
117
- event.stopPropagation();
118
- this.dispatchEvent(new Event('focus'));
119
- }
129
+ /**
130
+ * Focus event does not bubble, so we dispatch it manually
131
+ * on the host element to support adding focus listeners
132
+ * when the focusable element is placed in light DOM.
133
+ * @param {FocusEvent} event
134
+ * @protected
135
+ */
136
+ _onFocus(event) {
137
+ event.stopPropagation();
138
+ this.dispatchEvent(new Event('focus'));
139
+ }
120
140
 
121
- /**
122
- * Blur event does not bubble, so we dispatch it manually
123
- * on the host element to support adding blur listeners
124
- * when the focusable element is placed in light DOM.
125
- * @param {FocusEvent} event
126
- * @protected
127
- */
128
- _onBlur(event) {
129
- event.stopPropagation();
130
- this.dispatchEvent(new Event('blur'));
131
- }
141
+ /**
142
+ * Blur event does not bubble, so we dispatch it manually
143
+ * on the host element to support adding blur listeners
144
+ * when the focusable element is placed in light DOM.
145
+ * @param {FocusEvent} event
146
+ * @protected
147
+ */
148
+ _onBlur(event) {
149
+ event.stopPropagation();
150
+ this.dispatchEvent(new Event('blur'));
151
+ }
132
152
 
133
- /**
134
- * @param {Event} event
135
- * @return {boolean}
136
- * @protected
137
- * @override
138
- */
139
- _shouldSetFocus(event) {
140
- return event.target === this.focusElement;
141
- }
153
+ /**
154
+ * @param {Event} event
155
+ * @return {boolean}
156
+ * @protected
157
+ * @override
158
+ */
159
+ _shouldSetFocus(event) {
160
+ return event.target === this.focusElement;
161
+ }
142
162
 
143
- /**
144
- * @param {boolean} disabled
145
- * @protected
146
- */
147
- _disabledChanged(disabled) {
148
- super._disabledChanged(disabled);
163
+ /**
164
+ * @param {boolean} disabled
165
+ * @protected
166
+ */
167
+ _disabledChanged(disabled) {
168
+ super._disabledChanged(disabled);
149
169
 
150
- if (this.focusElement) {
151
- this.focusElement.disabled = disabled;
152
- }
170
+ if (this.focusElement) {
171
+ this.focusElement.disabled = disabled;
172
+ }
153
173
 
154
- if (disabled) {
155
- this.blur();
174
+ if (disabled) {
175
+ this.blur();
176
+ }
156
177
  }
157
178
  }
158
- };
159
-
160
- /**
161
- * A mixin to forward focus to an element in the light DOM.
162
- */
163
- export const DelegateFocusMixin = dedupingMixin(DelegateFocusMixinImplementation);
179
+ );
@@ -17,7 +17,7 @@ interface DelegateStateMixin {
17
17
  /**
18
18
  * A target element to which attributes and properties are delegated.
19
19
  */
20
- _delegateStateTarget: HTMLElement | null;
20
+ stateTarget: HTMLElement | null;
21
21
  }
22
22
 
23
23
  export { DelegateStateMixinConstructor, DelegateStateMixin };