@vaadin/field-base 22.0.0-alpha3 → 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 (77) hide show
  1. package/index.d.ts +9 -14
  2. package/index.js +9 -14
  3. package/package.json +24 -18
  4. package/src/aria-label-controller.d.ts +11 -0
  5. package/src/aria-label-controller.js +53 -0
  6. package/src/checked-mixin.d.ts +21 -0
  7. package/src/checked-mixin.js +54 -0
  8. package/src/delegate-focus-mixin.d.ts +2 -2
  9. package/src/delegate-focus-mixin.js +150 -133
  10. package/src/delegate-state-mixin.d.ts +23 -0
  11. package/src/delegate-state-mixin.js +125 -0
  12. package/src/field-mixin.d.ts +39 -0
  13. package/src/field-mixin.js +317 -0
  14. package/src/input-constraints-mixin.d.ts +2 -1
  15. package/src/input-constraints-mixin.js +105 -53
  16. package/src/input-control-mixin.d.ts +52 -0
  17. package/src/input-control-mixin.js +170 -0
  18. package/src/input-controller.d.ts +11 -0
  19. package/src/input-controller.js +35 -0
  20. package/src/input-field-mixin.d.ts +2 -16
  21. package/src/input-field-mixin.js +20 -97
  22. package/src/input-mixin.d.ts +1 -1
  23. package/src/input-mixin.js +156 -145
  24. package/src/label-mixin.d.ts +2 -2
  25. package/src/label-mixin.js +73 -60
  26. package/src/pattern-mixin.d.ts +2 -2
  27. package/src/pattern-mixin.js +13 -13
  28. package/src/shadow-focus-mixin.d.ts +21 -0
  29. package/src/shadow-focus-mixin.js +87 -0
  30. package/src/slot-controller.d.ts +8 -0
  31. package/src/slot-controller.js +36 -0
  32. package/src/slot-label-mixin.d.ts +20 -0
  33. package/src/slot-label-mixin.js +38 -0
  34. package/src/slot-styles-mixin.d.ts +24 -0
  35. package/src/slot-styles-mixin.js +76 -0
  36. package/src/slot-target-mixin.d.ts +32 -0
  37. package/src/slot-target-mixin.js +110 -0
  38. package/src/styles/clear-button-styles.d.ts +8 -0
  39. package/src/styles/clear-button-styles.js +21 -0
  40. package/src/styles/field-shared-styles.d.ts +8 -0
  41. package/src/styles/field-shared-styles.js +29 -0
  42. package/src/styles/input-field-container-styles.d.ts +8 -0
  43. package/src/styles/input-field-container-styles.js +16 -0
  44. package/src/styles/input-field-shared-styles.d.ts +8 -0
  45. package/src/styles/input-field-shared-styles.js +10 -0
  46. package/src/text-area-controller.d.ts +11 -0
  47. package/src/text-area-controller.js +38 -0
  48. package/src/validate-mixin.d.ts +1 -9
  49. package/src/validate-mixin.js +43 -118
  50. package/src/active-mixin.d.ts +0 -25
  51. package/src/active-mixin.js +0 -84
  52. package/src/aria-label-mixin.d.ts +0 -20
  53. package/src/aria-label-mixin.js +0 -71
  54. package/src/char-length-mixin.d.ts +0 -30
  55. package/src/char-length-mixin.js +0 -42
  56. package/src/clear-button-mixin.d.ts +0 -27
  57. package/src/clear-button-mixin.js +0 -80
  58. package/src/disabled-mixin.d.ts +0 -23
  59. package/src/disabled-mixin.js +0 -48
  60. package/src/field-aria-mixin.d.ts +0 -24
  61. package/src/field-aria-mixin.js +0 -61
  62. package/src/focus-mixin.d.ts +0 -33
  63. package/src/focus-mixin.js +0 -104
  64. package/src/forward-input-props-mixin.d.ts +0 -41
  65. package/src/forward-input-props-mixin.js +0 -110
  66. package/src/helper-text-mixin.d.ts +0 -24
  67. package/src/helper-text-mixin.js +0 -109
  68. package/src/input-slot-mixin.d.ts +0 -26
  69. package/src/input-slot-mixin.js +0 -71
  70. package/src/slot-mixin.d.ts +0 -23
  71. package/src/slot-mixin.js +0 -55
  72. package/src/tabindex-mixin.d.ts +0 -29
  73. package/src/tabindex-mixin.js +0 -78
  74. package/src/text-area-slot-mixin.d.ts +0 -21
  75. package/src/text-area-slot-mixin.js +0 -56
  76. package/src/text-field-mixin.d.ts +0 -21
  77. package/src/text-field-mixin.js +0 -17
@@ -0,0 +1,52 @@
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 { KeyboardMixin } from '@vaadin/component-base/src/keyboard-mixin.js';
7
+ import { FieldMixin } from './field-mixin.js';
8
+ import { InputConstraintsMixin } from './input-constraints-mixin.js';
9
+
10
+ /**
11
+ * A mixin to provide shared logic for the editable form input controls.
12
+ */
13
+ declare function InputControlMixin<T extends new (...args: any[]) => {}>(base: T): T & InputControlMixinConstructor;
14
+
15
+ interface InputControlMixinConstructor {
16
+ new (...args: any[]): InputControlMixin;
17
+ }
18
+
19
+ interface InputControlMixin extends KeyboardMixin, InputConstraintsMixin, FieldMixin {
20
+ /**
21
+ * Specify that the value should be automatically selected when the field gains focus.
22
+ */
23
+ autoselect: boolean;
24
+
25
+ /**
26
+ * Set to true to display the clear icon which clears the input.
27
+ * @attr {boolean} clear-button-visible
28
+ */
29
+ clearButtonVisible: boolean;
30
+
31
+ /**
32
+ * The name of this field.
33
+ */
34
+ name: string;
35
+
36
+ /**
37
+ * A hint to the user of what can be entered in the field.
38
+ */
39
+ placeholder: string;
40
+
41
+ /**
42
+ * When present, it specifies that the field is read-only.
43
+ */
44
+ readonly: boolean;
45
+
46
+ /**
47
+ * The text usually displayed in a tooltip popup when the mouse is over the field.
48
+ */
49
+ title: string;
50
+ }
51
+
52
+ export { InputControlMixin, InputControlMixinConstructor };
@@ -0,0 +1,170 @@
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 { KeyboardMixin } from '@vaadin/component-base/src/keyboard-mixin.js';
7
+ import { DelegateFocusMixin } from './delegate-focus-mixin.js';
8
+ import { FieldMixin } from './field-mixin.js';
9
+ import { InputConstraintsMixin } from './input-constraints-mixin.js';
10
+
11
+ /**
12
+ * A mixin to provide shared logic for the editable form input controls.
13
+ *
14
+ * @polymerMixin
15
+ * @mixes DelegateFocusMixin
16
+ * @mixes FieldMixin
17
+ * @mixes InputConstraintsMixin
18
+ * @mixes KeyboardMixin
19
+ */
20
+ export const InputControlMixin = (superclass) =>
21
+ class InputControlMixinClass extends DelegateFocusMixin(
22
+ InputConstraintsMixin(FieldMixin(KeyboardMixin(superclass)))
23
+ ) {
24
+ static get properties() {
25
+ return {
26
+ /**
27
+ * Specify that the value should be automatically selected when the field gains focus.
28
+ */
29
+ autoselect: {
30
+ type: Boolean,
31
+ value: false
32
+ },
33
+
34
+ /**
35
+ * Set to true to display the clear icon which clears the input.
36
+ * @attr {boolean} clear-button-visible
37
+ */
38
+ clearButtonVisible: {
39
+ type: Boolean,
40
+ reflectToAttribute: true,
41
+ value: false
42
+ },
43
+
44
+ /**
45
+ * The name of this field.
46
+ */
47
+ name: {
48
+ type: String,
49
+ reflectToAttribute: true
50
+ },
51
+
52
+ /**
53
+ * A hint to the user of what can be entered in the field.
54
+ */
55
+ placeholder: {
56
+ type: String,
57
+ reflectToAttribute: true
58
+ },
59
+
60
+ /**
61
+ * When present, it specifies that the field is read-only.
62
+ */
63
+ readonly: {
64
+ type: Boolean,
65
+ value: false,
66
+ reflectToAttribute: true
67
+ },
68
+
69
+ /**
70
+ * The text usually displayed in a tooltip popup when the mouse is over the field.
71
+ */
72
+ title: {
73
+ type: String,
74
+ reflectToAttribute: true
75
+ }
76
+ };
77
+ }
78
+
79
+ static get delegateAttrs() {
80
+ return [...super.delegateAttrs, 'name', 'type', 'placeholder', 'readonly', 'invalid', 'title'];
81
+ }
82
+
83
+ /**
84
+ * Any element extending this mixin is required to implement this getter.
85
+ * It returns the reference to the clear button element.
86
+ * @protected
87
+ * @return {Element | null | undefined}
88
+ */
89
+ get clearElement() {
90
+ console.warn(`Please implement the 'clearElement' property in <${this.localName}>`);
91
+ return null;
92
+ }
93
+
94
+ /** @protected */
95
+ ready() {
96
+ super.ready();
97
+
98
+ if (this.clearElement) {
99
+ this.clearElement.addEventListener('click', (e) => this._onClearButtonClick(e));
100
+ }
101
+ }
102
+
103
+ /**
104
+ * @param {Event} event
105
+ * @protected
106
+ */
107
+ _onClearButtonClick(event) {
108
+ event.preventDefault();
109
+ this.inputElement.focus();
110
+ this.clear();
111
+ this.inputElement.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
112
+ this.inputElement.dispatchEvent(new Event('change', { bubbles: true }));
113
+ }
114
+
115
+ /**
116
+ * Override an event listener from `DelegateFocusMixin`.
117
+ * @param {FocusEvent} event
118
+ * @protected
119
+ * @override
120
+ */
121
+ _onFocus(event) {
122
+ super._onFocus(event);
123
+
124
+ if (this.autoselect && this.inputElement) {
125
+ this.inputElement.select();
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Override an event listener inherited from `KeydownMixin` to clear on Esc.
131
+ * Components that extend this mixin can prevent this behavior by overriding
132
+ * this method without calling `super._onKeyDown` to provide custom logic.
133
+ * @param {KeyboardEvent} event
134
+ * @protected
135
+ * @override
136
+ */
137
+ _onKeyDown(event) {
138
+ super._onKeyDown(event);
139
+
140
+ if (event.key === 'Escape' && this.clearButtonVisible) {
141
+ const dispatchChange = !!this.value;
142
+ this.clear();
143
+ dispatchChange && this.inputElement.dispatchEvent(new Event('change', { bubbles: true }));
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Override an event listener inherited from `InputMixin`
149
+ * to capture native `change` event and make sure that
150
+ * a new one is dispatched after validation runs.
151
+ * @param {Event} event
152
+ * @protected
153
+ * @override
154
+ */
155
+ _onChange(event) {
156
+ event.stopPropagation();
157
+
158
+ this.validate();
159
+
160
+ this.dispatchEvent(
161
+ new CustomEvent('change', {
162
+ detail: {
163
+ sourceEvent: event
164
+ },
165
+ bubbles: event.bubbles,
166
+ cancelable: event.cancelable
167
+ })
168
+ );
169
+ }
170
+ };
@@ -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 { SlotController } from './slot-controller.js';
7
+
8
+ /**
9
+ * A controller to create and initialize slotted `<input>` element.
10
+ */
11
+ export class InputController implements SlotController {}
@@ -0,0 +1,35 @@
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 { SlotController } from './slot-controller.js';
7
+
8
+ /**
9
+ * A controller to create and initialize slotted `<input>` element.
10
+ */
11
+ export class InputController extends SlotController {
12
+ constructor(host, callback) {
13
+ super(host, [
14
+ 'input',
15
+ () => document.createElement('input'),
16
+ (host, node) => {
17
+ if (host.value) {
18
+ node.setAttribute('value', host.value);
19
+ }
20
+ if (host.type) {
21
+ node.setAttribute('type', host.type);
22
+ }
23
+
24
+ // Ensure every instance has unique ID
25
+ const uniqueId = (InputController._uniqueInputId = 1 + InputController._uniqueInputId || 0);
26
+ host._inputId = `${host.localName}-${uniqueId}`;
27
+ node.id = host._inputId;
28
+
29
+ if (typeof callback == 'function') {
30
+ callback(node);
31
+ }
32
+ }
33
+ ]);
34
+ }
35
+ }
@@ -3,11 +3,7 @@
3
3
  * Copyright (c) 2021 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { AriaLabelMixin } from './aria-label-mixin.js';
7
- import { ClearButtonMixin } from './clear-button-mixin.js';
8
- import { DelegateFocusMixin } from './delegate-focus-mixin.js';
9
- import { FieldAriaMixin } from './field-aria-mixin.js';
10
- import { ForwardInputPropsMixin } from './forward-input-props-mixin.js';
6
+ import { InputControlMixin } from './input-control-mixin.js';
11
7
 
12
8
  /**
13
9
  * A mixin to provide logic for vaadin-text-field and related components.
@@ -18,12 +14,7 @@ interface InputFieldMixinConstructor {
18
14
  new (...args: any[]): InputFieldMixin;
19
15
  }
20
16
 
21
- interface InputFieldMixin
22
- extends AriaLabelMixin,
23
- ClearButtonMixin,
24
- DelegateFocusMixin,
25
- FieldAriaMixin,
26
- ForwardInputPropsMixin {
17
+ interface InputFieldMixin extends InputControlMixin {
27
18
  /**
28
19
  * Whether the value of the control can be automatically completed by the browser.
29
20
  * List of available options at:
@@ -50,11 +41,6 @@ interface InputFieldMixin
50
41
  * none: No capitalization.
51
42
  */
52
43
  autocapitalize: 'on' | 'off' | 'none' | 'characters' | 'words' | 'sentences' | undefined;
53
-
54
- /**
55
- * Specify that the value should be automatically selected when the field gains focus.
56
- */
57
- autoselect: boolean;
58
44
  }
59
45
 
60
46
  export { InputFieldMixin, InputFieldMixinConstructor };
@@ -3,19 +3,16 @@
3
3
  * Copyright (c) 2021 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { Debouncer } from '@polymer/polymer/lib/utils/debounce.js';
7
- import { animationFrame } from '@polymer/polymer/lib/utils/async.js';
8
- import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
9
- import { AriaLabelMixin } from './aria-label-mixin.js';
10
- import { ClearButtonMixin } from './clear-button-mixin.js';
11
- import { DelegateFocusMixin } from './delegate-focus-mixin.js';
12
- import { FieldAriaMixin } from './field-aria-mixin.js';
13
- import { ForwardInputPropsMixin } from './forward-input-props-mixin.js';
6
+ import { InputControlMixin } from './input-control-mixin.js';
14
7
 
15
- const InputFieldMixinImplementation = (superclass) =>
16
- class InputFieldMixinClass extends ClearButtonMixin(
17
- FieldAriaMixin(ForwardInputPropsMixin(AriaLabelMixin(DelegateFocusMixin(superclass))))
18
- ) {
8
+ /**
9
+ * A mixin to provide logic for vaadin-text-field and related components.
10
+ *
11
+ * @polymerMixin
12
+ * @mixes InputControlMixin
13
+ */
14
+ export const InputFieldMixin = (superclass) =>
15
+ class InputFieldMixinClass extends InputControlMixin(superclass) {
19
16
  static get properties() {
20
17
  return {
21
18
  /**
@@ -49,65 +46,35 @@ const InputFieldMixinImplementation = (superclass) =>
49
46
  */
50
47
  autocapitalize: {
51
48
  type: String
52
- },
53
-
54
- /**
55
- * Specify that the value should be automatically selected when the field gains focus.
56
- */
57
- autoselect: {
58
- type: Boolean,
59
- value: false
60
49
  }
61
50
  };
62
51
  }
63
52
 
64
- static get forwardProps() {
65
- return [...super.forwardProps, 'autocapitalize', 'autocomplete', 'autocorrect'];
66
- }
67
-
68
- static get observers() {
69
- return ['__observeOffsetHeight(errorMessage, invalid, label, helperText)'];
53
+ static get delegateAttrs() {
54
+ return [...super.delegateAttrs, 'autocapitalize', 'autocomplete', 'autocorrect'];
70
55
  }
71
56
 
72
57
  /**
73
- * Element used by `FieldAriaMixin` to set ARIA attributes.
58
+ * @param {HTMLElement} input
74
59
  * @protected
60
+ * @override
75
61
  */
76
- get _ariaTarget() {
77
- return this.inputElement;
78
- }
79
-
80
- /** @protected */
81
- connectedCallback() {
82
- super.connectedCallback();
62
+ _inputElementChanged(input) {
63
+ super._inputElementChanged(input);
83
64
 
84
- if (this.inputElement) {
65
+ if (input) {
85
66
  // Discard value set on the custom slotted input.
86
- if (this.inputElement.value && this.inputElement.value !== this.value) {
67
+ if (input.value && input.value !== this.value) {
87
68
  console.warn(`Please define value on the <${this.localName}> component!`);
88
- this.inputElement.value = '';
69
+ input.value = '';
89
70
  }
90
71
 
91
72
  if (this.value) {
92
- this.inputElement.value = this.value;
73
+ input.value = this.value;
93
74
  }
94
75
  }
95
76
  }
96
77
 
97
- /** @protected */
98
- ready() {
99
- super.ready();
100
-
101
- // Lumo theme defines a max-height transition for the "error-message"
102
- // part on invalid state change.
103
- const errorPart = this.shadowRoot.querySelector('[part="error-message"]');
104
- if (errorPart) {
105
- errorPart.addEventListener('transitionend', () => {
106
- this.__observeOffsetHeight();
107
- });
108
- }
109
- }
110
-
111
78
  // Workaround for https://github.com/Polymer/polymer/issues/5259
112
79
  get __data() {
113
80
  return this.__dataValue || {};
@@ -118,21 +85,7 @@ const InputFieldMixinImplementation = (superclass) =>
118
85
  }
119
86
 
120
87
  /**
121
- * Override an event listener from `DelegatesFocusMixin`.
122
- * @param {FocusEvent} event
123
- * @protected
124
- * @override
125
- */
126
- _onFocus(event) {
127
- super._onFocus(event);
128
-
129
- if (this.autoselect && this.inputElement) {
130
- this.inputElement.select();
131
- }
132
- }
133
-
134
- /**
135
- * Override an event listener from `DelegatesFocusMixin`.
88
+ * Override an event listener from `DelegateFocusMixin`.
136
89
  * @param {FocusEvent} event
137
90
  * @protected
138
91
  * @override
@@ -143,31 +96,6 @@ const InputFieldMixinImplementation = (superclass) =>
143
96
  this.validate();
144
97
  }
145
98
 
146
- /**
147
- * Dispatch an event if a specific size measurement property has changed.
148
- * Supporting multiple properties here is needed for `vaadin-text-area`.
149
- * @protected
150
- */
151
- _dispatchIronResizeEventIfNeeded(prop, value) {
152
- const oldSize = '__old' + prop;
153
- if (this[oldSize] !== undefined && this[oldSize] !== value) {
154
- this.dispatchEvent(new CustomEvent('iron-resize', { bubbles: true, composed: true }));
155
- }
156
-
157
- this[oldSize] = value;
158
- }
159
-
160
- /** @private */
161
- __observeOffsetHeight() {
162
- this.__observeOffsetHeightDebouncer = Debouncer.debounce(
163
- this.__observeOffsetHeightDebouncer,
164
- animationFrame,
165
- () => {
166
- this._dispatchIronResizeEventIfNeeded('Height', this.offsetHeight);
167
- }
168
- );
169
- }
170
-
171
99
  /**
172
100
  * Override a method from `InputMixin` to validate the field
173
101
  * when a new value is set programmatically.
@@ -183,8 +111,3 @@ const InputFieldMixinImplementation = (superclass) =>
183
111
  }
184
112
  }
185
113
  };
186
-
187
- /**
188
- * A mixin to provide logic for vaadin-text-field and related components.
189
- */
190
- export const InputFieldMixin = dedupingMixin(InputFieldMixinImplementation);
@@ -20,7 +20,7 @@ interface InputMixin {
20
20
  * Any component implementing this mixin is expected to provide it
21
21
  * by using `this._setInputElement(input)` Polymer API.
22
22
  *
23
- * A typical case is using `InputSlotMixin` that does this automatically.
23
+ * A typical case is using `InputController` that does this automatically.
24
24
  * However, the input element does not have to always be native <input>:
25
25
  * as an example, <vaadin-combo-box-light> accepts other components.
26
26
  */