@vaadin/vaadin-time-picker 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 +23 -31
- package/src/vaadin-time-picker.d.ts +13 -253
- package/src/vaadin-time-picker.js +5 -725
- package/theme/lumo/vaadin-time-picker.js +6 -3
- package/theme/material/vaadin-time-picker.js +6 -2
- package/vaadin-time-picker.d.ts +0 -1
- package/src/interfaces.d.ts +0 -31
- package/src/vaadin-time-picker-text-field.js +0 -41
- package/theme/lumo/vaadin-time-picker-styles.js +0 -12
- package/theme/lumo/vaadin-time-picker-text-field-styles.js +0 -18
- package/theme/material/vaadin-time-picker-styles.js +0 -15
package/package.json
CHANGED
|
@@ -1,9 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/vaadin-time-picker",
|
|
3
|
-
"version": "22.0.0-
|
|
3
|
+
"version": "22.0.0-beta1",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
4
7
|
"description": "vaadin-time-picker",
|
|
8
|
+
"license": "Apache-2.0",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/vaadin/web-components.git",
|
|
12
|
+
"directory": "packages/vaadin-time-picker"
|
|
13
|
+
},
|
|
14
|
+
"author": "Vaadin Ltd",
|
|
15
|
+
"homepage": "https://vaadin.com/components",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/vaadin/vaadin-time-picker/issues"
|
|
18
|
+
},
|
|
5
19
|
"main": "vaadin-time-picker.js",
|
|
6
20
|
"module": "vaadin-time-picker.js",
|
|
21
|
+
"files": [
|
|
22
|
+
"src",
|
|
23
|
+
"theme",
|
|
24
|
+
"vaadin-*.d.ts",
|
|
25
|
+
"vaadin-*.js"
|
|
26
|
+
],
|
|
7
27
|
"keywords": [
|
|
8
28
|
"Vaadin",
|
|
9
29
|
"vaadin-time-picker",
|
|
@@ -11,36 +31,8 @@
|
|
|
11
31
|
"web-component",
|
|
12
32
|
"polymer"
|
|
13
33
|
],
|
|
14
|
-
"repository": "vaadin/vaadin-time-picker",
|
|
15
|
-
"author": "Vaadin Ltd",
|
|
16
|
-
"license": "Apache-2.0",
|
|
17
|
-
"bugs": {
|
|
18
|
-
"url": "https://github.com/vaadin/vaadin-time-picker/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
|
-
"@
|
|
29
|
-
"@vaadin/vaadin-combo-box": "^22.0.0-alpha6",
|
|
30
|
-
"@vaadin/vaadin-control-state-mixin": "^22.0.0-alpha6",
|
|
31
|
-
"@vaadin/vaadin-element-mixin": "^22.0.0-alpha6",
|
|
32
|
-
"@vaadin/vaadin-lumo-styles": "^22.0.0-alpha6",
|
|
33
|
-
"@vaadin/vaadin-material-styles": "^22.0.0-alpha6",
|
|
34
|
-
"@vaadin/vaadin-text-field": "^22.0.0-alpha6",
|
|
35
|
-
"@vaadin/vaadin-themable-mixin": "^22.0.0-alpha6"
|
|
36
|
-
},
|
|
37
|
-
"devDependencies": {
|
|
38
|
-
"@esm-bundle/chai": "^4.3.4",
|
|
39
|
-
"@vaadin/testing-helpers": "^0.3.0",
|
|
40
|
-
"sinon": "^9.2.0"
|
|
41
|
-
},
|
|
42
|
-
"publishConfig": {
|
|
43
|
-
"access": "public"
|
|
35
|
+
"@vaadin/time-picker": "22.0.0-beta1"
|
|
44
36
|
},
|
|
45
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "4cf8a9d0504994200c610e44b3676114fef49c1e"
|
|
46
38
|
}
|
|
@@ -1,257 +1,17 @@
|
|
|
1
|
-
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
2
|
-
|
|
3
|
-
import { ElementMixin } from '@vaadin/vaadin-element-mixin/vaadin-element-mixin.js';
|
|
4
|
-
|
|
5
|
-
import { ControlStateMixin } from '@vaadin/vaadin-control-state-mixin/vaadin-control-state-mixin.js';
|
|
6
|
-
|
|
7
|
-
import { TimePickerEventMap, TimePickerI18n, TimePickerTime } from './interfaces';
|
|
8
|
-
|
|
9
1
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* <vaadin-time-picker></vaadin-time-picker>
|
|
14
|
-
* ```
|
|
15
|
-
* ```js
|
|
16
|
-
* timePicker.value = '14:30';
|
|
17
|
-
* ```
|
|
18
|
-
*
|
|
19
|
-
* When the selected `value` is changed, a `value-changed` event is triggered.
|
|
20
|
-
*
|
|
21
|
-
* ### Styling
|
|
22
|
-
*
|
|
23
|
-
* The following custom properties are available for styling:
|
|
24
|
-
*
|
|
25
|
-
* Part name | Description
|
|
26
|
-
* ----------------|----------------
|
|
27
|
-
* `toggle-button` | The toggle button
|
|
28
|
-
*
|
|
29
|
-
* See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
|
|
30
|
-
*
|
|
31
|
-
* The following state attributes are available for styling:
|
|
32
|
-
*
|
|
33
|
-
* Attribute | Description | Part name
|
|
34
|
-
* -------------|-------------|------------
|
|
35
|
-
* `disabled` | Set to a disabled time picker | :host
|
|
36
|
-
* `readonly` | Set to a read only time picker | :host
|
|
37
|
-
* `invalid` | Set when the element is invalid | :host
|
|
38
|
-
* `focused` | Set when the element is focused | :host
|
|
39
|
-
* `focus-ring` | Set when the element is keyboard focused | :host
|
|
40
|
-
*
|
|
41
|
-
* ### Internal components
|
|
42
|
-
*
|
|
43
|
-
* In addition to `<vaadin-select>` itself, the following internal
|
|
44
|
-
* components are themable:
|
|
45
|
-
*
|
|
46
|
-
* - `<vaadin-time-picker-text-field>` - has the same API as [`<vaadin-text-field>`](#/elements/vaadin-text-field).
|
|
47
|
-
* - [`<vaadin-combo-box-light>`](#/elements/vaadin-combo-box-light).
|
|
48
|
-
*
|
|
49
|
-
* Note: the `theme` attribute value set on `<vaadin-time-picker>` is
|
|
50
|
-
* propagated to the internal components listed above.
|
|
51
|
-
*
|
|
52
|
-
* @fires {Event} change - Fired when the user commits a value change.
|
|
53
|
-
* @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
|
|
54
|
-
* @fires {CustomEvent} value-changed - Fired when the `value` property changes.
|
|
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/
|
|
55
5
|
*/
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Focusable element used by vaadin-control-state-mixin
|
|
59
|
-
*/
|
|
60
|
-
readonly focusElement: HTMLElement;
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Set to true to disable this input.
|
|
64
|
-
*/
|
|
65
|
-
disabled: boolean;
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* The name of this element.
|
|
69
|
-
*/
|
|
70
|
-
name: string | null | undefined;
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* The time value for this element.
|
|
74
|
-
*
|
|
75
|
-
* Supported time formats are in ISO 8601:
|
|
76
|
-
* - `hh:mm` (default)
|
|
77
|
-
* - `hh:mm:ss`
|
|
78
|
-
* - `hh:mm:ss.fff`
|
|
79
|
-
*/
|
|
80
|
-
value: string;
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* The label for this element.
|
|
84
|
-
*/
|
|
85
|
-
label: string | null | undefined;
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Set to true to mark the input as required.
|
|
89
|
-
*/
|
|
90
|
-
required: boolean;
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Set to true to prevent the user from entering invalid input.
|
|
94
|
-
* @attr {boolean} prevent-invalid-input
|
|
95
|
-
*/
|
|
96
|
-
preventInvalidInput: boolean | null | undefined;
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* A pattern to validate the `input` with.
|
|
100
|
-
*/
|
|
101
|
-
pattern: string | null | undefined;
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* The error message to display when the input is invalid.
|
|
105
|
-
* @attr {string} error-message
|
|
106
|
-
*/
|
|
107
|
-
errorMessage: string | null | undefined;
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* String used for the helper text.
|
|
111
|
-
* @attr {string} helper-text
|
|
112
|
-
*/
|
|
113
|
-
helperText: string | null | undefined;
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* A placeholder string in addition to the label.
|
|
117
|
-
*/
|
|
118
|
-
placeholder: string;
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Set to true to prevent user picking a date or typing in the input.
|
|
122
|
-
*/
|
|
123
|
-
readonly: boolean;
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Set to true if the value is invalid.
|
|
127
|
-
*/
|
|
128
|
-
invalid: boolean;
|
|
6
|
+
import { TimePicker } from '@vaadin/time-picker';
|
|
129
7
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
* - `hh:mm:ss`
|
|
136
|
-
* - `hh:mm:ss.fff`
|
|
137
|
-
*/
|
|
138
|
-
min: string;
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Maximum time allowed.
|
|
142
|
-
*
|
|
143
|
-
* Supported time formats are in ISO 8601:
|
|
144
|
-
* - `hh:mm`
|
|
145
|
-
* - `hh:mm:ss`
|
|
146
|
-
* - `hh:mm:ss.fff`
|
|
147
|
-
*/
|
|
148
|
-
max: string;
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Specifies the number of valid intervals in a day used for
|
|
152
|
-
* configuring the items displayed in the selection box.
|
|
153
|
-
*
|
|
154
|
-
* It also configures the precision of the value string. By default
|
|
155
|
-
* the component formats values as `hh:mm` but setting a step value
|
|
156
|
-
* lower than one minute or one second, format resolution changes to
|
|
157
|
-
* `hh:mm:ss` and `hh:mm:ss.fff` respectively.
|
|
158
|
-
*
|
|
159
|
-
* Unit must be set in seconds, and for correctly configuring intervals
|
|
160
|
-
* in the dropdown, it need to evenly divide a day.
|
|
161
|
-
*
|
|
162
|
-
* Note: it is possible to define step that is dividing an hour in inexact
|
|
163
|
-
* fragments (i.e. 5760 seconds which equals 1 hour 36 minutes), but it is
|
|
164
|
-
* not recommended to use it for better UX experience.
|
|
165
|
-
*/
|
|
166
|
-
step: number | null | undefined;
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Set to true to display the clear icon which clears the input.
|
|
170
|
-
* @attr {boolean} clear-button-visible
|
|
171
|
-
*/
|
|
172
|
-
clearButtonVisible: boolean;
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Set true to prevent the overlay from opening automatically.
|
|
176
|
-
* @attr {boolean} auto-open-disabled
|
|
177
|
-
*/
|
|
178
|
-
autoOpenDisabled: boolean | null | undefined;
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* The object used to localize this component.
|
|
182
|
-
* To change the default localization, replace the entire
|
|
183
|
-
* _i18n_ object or just the property you want to modify.
|
|
184
|
-
*
|
|
185
|
-
* The object has the following JSON structure:
|
|
186
|
-
*
|
|
187
|
-
* {
|
|
188
|
-
* // A function to format given `Object` as
|
|
189
|
-
* // time string. Object is in the format `{ hours: ..., minutes: ..., seconds: ..., milliseconds: ... }`
|
|
190
|
-
* formatTime: (time) => {
|
|
191
|
-
* // returns a string representation of the given
|
|
192
|
-
* // object in `hh` / 'hh:mm' / 'hh:mm:ss' / 'hh:mm:ss.fff' - formats
|
|
193
|
-
* },
|
|
194
|
-
*
|
|
195
|
-
* // A function to parse the given text to an `Object` in the format
|
|
196
|
-
* // `{ hours: ..., minutes: ..., seconds: ..., milliseconds: ... }`.
|
|
197
|
-
* // Must properly parse (at least) text
|
|
198
|
-
* // formatted by `formatTime`.
|
|
199
|
-
* parseTime: text => {
|
|
200
|
-
* // Parses a string in object/string that can be formatted by`formatTime`.
|
|
201
|
-
* }
|
|
202
|
-
*
|
|
203
|
-
* // Translation of the time selector icon button title.
|
|
204
|
-
* selector: 'Time selector',
|
|
205
|
-
*
|
|
206
|
-
* // Translation of the time selector clear button title.
|
|
207
|
-
* clear: 'Clear'
|
|
208
|
-
* }
|
|
209
|
-
*/
|
|
210
|
-
i18n: TimePickerI18n;
|
|
211
|
-
|
|
212
|
-
_getInputElement(): HTMLElement;
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Returns true if `value` is valid, and sets the `invalid` flag appropriately.
|
|
216
|
-
*
|
|
217
|
-
* @returns True if the value is valid and sets the `invalid` flag appropriately
|
|
218
|
-
*/
|
|
219
|
-
validate(): boolean;
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Returns true if `time` satisfies the `min` and `max` constraints (if any).
|
|
223
|
-
*
|
|
224
|
-
* @param time Value to check against constraints
|
|
225
|
-
* @returns True if `time` satisfies the constraints
|
|
226
|
-
*/
|
|
227
|
-
_timeAllowed(time: TimePickerTime): boolean;
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Returns true if the current input value satisfies all constraints (if any)
|
|
231
|
-
*
|
|
232
|
-
* You can override the `checkValidity` method for custom validations.
|
|
233
|
-
*
|
|
234
|
-
* @returns True if the value is valid
|
|
235
|
-
*/
|
|
236
|
-
checkValidity(): boolean;
|
|
237
|
-
|
|
238
|
-
addEventListener<K extends keyof TimePickerEventMap>(
|
|
239
|
-
type: K,
|
|
240
|
-
listener: (this: TimePickerElement, ev: TimePickerEventMap[K]) => void,
|
|
241
|
-
options?: boolean | AddEventListenerOptions
|
|
242
|
-
): void;
|
|
243
|
-
|
|
244
|
-
removeEventListener<K extends keyof TimePickerEventMap>(
|
|
245
|
-
type: K,
|
|
246
|
-
listener: (this: TimePickerElement, ev: TimePickerEventMap[K]) => void,
|
|
247
|
-
options?: boolean | EventListenerOptions
|
|
248
|
-
): void;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
declare global {
|
|
252
|
-
interface HTMLElementTagNameMap {
|
|
253
|
-
'vaadin-time-picker': TimePickerElement;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
8
|
+
export * from '@vaadin/time-picker/src/vaadin-time-picker.js';
|
|
9
|
+
/**
|
|
10
|
+
* @deprecated Import `TimePicker` from `@vaadin/time-picker` instead.
|
|
11
|
+
*/
|
|
12
|
+
export type TimePickerElement = TimePicker;
|
|
256
13
|
|
|
257
|
-
|
|
14
|
+
/**
|
|
15
|
+
* @deprecated Import `TimePicker` from `@vaadin/time-picker` instead.
|
|
16
|
+
*/
|
|
17
|
+
export const TimePickerElement: typeof TimePicker;
|
|
@@ -3,731 +3,11 @@
|
|
|
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 {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import { ControlStateMixin } from '@vaadin/vaadin-control-state-mixin/vaadin-control-state-mixin.js';
|
|
10
|
-
import '@vaadin/vaadin-combo-box/src/vaadin-combo-box-light.js';
|
|
11
|
-
import './vaadin-time-picker-text-field.js';
|
|
6
|
+
import { TimePicker } from '@vaadin/time-picker';
|
|
7
|
+
|
|
8
|
+
export * from '@vaadin/time-picker/src/vaadin-time-picker.js';
|
|
12
9
|
|
|
13
10
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* ```html
|
|
17
|
-
* <vaadin-time-picker></vaadin-time-picker>
|
|
18
|
-
* ```
|
|
19
|
-
* ```js
|
|
20
|
-
* timePicker.value = '14:30';
|
|
21
|
-
* ```
|
|
22
|
-
*
|
|
23
|
-
* When the selected `value` is changed, a `value-changed` event is triggered.
|
|
24
|
-
*
|
|
25
|
-
* ### Styling
|
|
26
|
-
*
|
|
27
|
-
* The following custom properties are available for styling:
|
|
28
|
-
*
|
|
29
|
-
* Part name | Description
|
|
30
|
-
* ----------------|----------------
|
|
31
|
-
* `toggle-button` | The toggle button
|
|
32
|
-
*
|
|
33
|
-
* See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
|
|
34
|
-
*
|
|
35
|
-
* The following state attributes are available for styling:
|
|
36
|
-
*
|
|
37
|
-
* Attribute | Description | Part name
|
|
38
|
-
* -------------|-------------|------------
|
|
39
|
-
* `disabled` | Set to a disabled time picker | :host
|
|
40
|
-
* `readonly` | Set to a read only time picker | :host
|
|
41
|
-
* `invalid` | Set when the element is invalid | :host
|
|
42
|
-
* `focused` | Set when the element is focused | :host
|
|
43
|
-
* `focus-ring` | Set when the element is keyboard focused | :host
|
|
44
|
-
*
|
|
45
|
-
* ### Internal components
|
|
46
|
-
*
|
|
47
|
-
* In addition to `<vaadin-select>` itself, the following internal
|
|
48
|
-
* components are themable:
|
|
49
|
-
*
|
|
50
|
-
* - `<vaadin-time-picker-text-field>` - has the same API as [`<vaadin-text-field>`](#/elements/vaadin-text-field).
|
|
51
|
-
* - [`<vaadin-combo-box-light>`](#/elements/vaadin-combo-box-light).
|
|
52
|
-
*
|
|
53
|
-
* Note: the `theme` attribute value set on `<vaadin-time-picker>` is
|
|
54
|
-
* propagated to the internal components listed above.
|
|
55
|
-
*
|
|
56
|
-
* @fires {Event} change - Fired when the user commits a value change.
|
|
57
|
-
* @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
|
|
58
|
-
* @fires {CustomEvent} value-changed - Fired when the `value` property changes.
|
|
59
|
-
*
|
|
60
|
-
* @extends HTMLElement
|
|
61
|
-
* @mixes ElementMixin
|
|
62
|
-
* @mixes ControlStateMixin
|
|
63
|
-
* @mixes ThemableMixin
|
|
11
|
+
* @deprecated Import `TimePicker` from `@vaadin/time-picker` instead.
|
|
64
12
|
*/
|
|
65
|
-
|
|
66
|
-
static get template() {
|
|
67
|
-
return html`
|
|
68
|
-
<style>
|
|
69
|
-
:host {
|
|
70
|
-
display: inline-block;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
:host([hidden]) {
|
|
74
|
-
display: none !important;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
[part~='toggle-button'] {
|
|
78
|
-
cursor: pointer;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.input {
|
|
82
|
-
width: 100%;
|
|
83
|
-
min-width: 0;
|
|
84
|
-
}
|
|
85
|
-
</style>
|
|
86
|
-
<vaadin-combo-box-light
|
|
87
|
-
allow-custom-value=""
|
|
88
|
-
filtered-items="[[__dropdownItems]]"
|
|
89
|
-
disabled="[[disabled]]"
|
|
90
|
-
readonly="[[readonly]]"
|
|
91
|
-
auto-open-disabled="[[autoOpenDisabled]]"
|
|
92
|
-
dir="ltr"
|
|
93
|
-
theme$="[[theme]]"
|
|
94
|
-
>
|
|
95
|
-
<vaadin-time-picker-text-field
|
|
96
|
-
class="input"
|
|
97
|
-
name="[[name]]"
|
|
98
|
-
invalid="[[invalid]]"
|
|
99
|
-
autocomplete="off"
|
|
100
|
-
label="[[label]]"
|
|
101
|
-
required="[[required]]"
|
|
102
|
-
disabled="[[disabled]]"
|
|
103
|
-
prevent-invalid-input="[[preventInvalidInput]]"
|
|
104
|
-
pattern="[[pattern]]"
|
|
105
|
-
error-message="[[errorMessage]]"
|
|
106
|
-
autofocus="[[autofocus]]"
|
|
107
|
-
placeholder="[[placeholder]]"
|
|
108
|
-
readonly="[[readonly]]"
|
|
109
|
-
role="application"
|
|
110
|
-
aria-live="assertive"
|
|
111
|
-
min$="[[min]]"
|
|
112
|
-
max$="[[max]]"
|
|
113
|
-
aria-label$="[[label]]"
|
|
114
|
-
clear-button-visible="[[clearButtonVisible]]"
|
|
115
|
-
i18n="[[i18n]]"
|
|
116
|
-
helper-text="[[helperText]]"
|
|
117
|
-
theme$="[[theme]]"
|
|
118
|
-
>
|
|
119
|
-
<slot name="helper" slot="helper">[[helperText]]</slot>
|
|
120
|
-
<span
|
|
121
|
-
slot="suffix"
|
|
122
|
-
part="toggle-button"
|
|
123
|
-
class="toggle-button"
|
|
124
|
-
role="button"
|
|
125
|
-
aria-label$="[[i18n.selector]]"
|
|
126
|
-
></span>
|
|
127
|
-
</vaadin-time-picker-text-field>
|
|
128
|
-
</vaadin-combo-box-light>
|
|
129
|
-
`;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
static get is() {
|
|
133
|
-
return 'vaadin-time-picker';
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
static get properties() {
|
|
137
|
-
return {
|
|
138
|
-
/**
|
|
139
|
-
* The name of this element.
|
|
140
|
-
*/
|
|
141
|
-
name: {
|
|
142
|
-
type: String
|
|
143
|
-
},
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* The time value for this element.
|
|
147
|
-
*
|
|
148
|
-
* Supported time formats are in ISO 8601:
|
|
149
|
-
* - `hh:mm` (default)
|
|
150
|
-
* - `hh:mm:ss`
|
|
151
|
-
* - `hh:mm:ss.fff`
|
|
152
|
-
* @type {string}
|
|
153
|
-
*/
|
|
154
|
-
value: {
|
|
155
|
-
type: String,
|
|
156
|
-
observer: '__valueChanged',
|
|
157
|
-
notify: true,
|
|
158
|
-
value: ''
|
|
159
|
-
},
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* The label for this element.
|
|
163
|
-
*/
|
|
164
|
-
label: {
|
|
165
|
-
type: String,
|
|
166
|
-
reflectToAttribute: true
|
|
167
|
-
},
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Set to true to mark the input as required.
|
|
171
|
-
* @type {boolean}
|
|
172
|
-
*/
|
|
173
|
-
required: {
|
|
174
|
-
type: Boolean,
|
|
175
|
-
value: false
|
|
176
|
-
},
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Set to true to disable this input.
|
|
180
|
-
* @type {boolean}
|
|
181
|
-
*/
|
|
182
|
-
disabled: {
|
|
183
|
-
type: Boolean,
|
|
184
|
-
value: false
|
|
185
|
-
},
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Set to true to prevent the user from entering invalid input.
|
|
189
|
-
* @attr {boolean} prevent-invalid-input
|
|
190
|
-
*/
|
|
191
|
-
preventInvalidInput: {
|
|
192
|
-
type: Boolean
|
|
193
|
-
},
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* A pattern to validate the `input` with.
|
|
197
|
-
*/
|
|
198
|
-
pattern: {
|
|
199
|
-
type: String
|
|
200
|
-
},
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* The error message to display when the input is invalid.
|
|
204
|
-
* @attr {string} error-message
|
|
205
|
-
*/
|
|
206
|
-
errorMessage: {
|
|
207
|
-
type: String
|
|
208
|
-
},
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* String used for the helper text.
|
|
212
|
-
* @attr {string} helper-text
|
|
213
|
-
*/
|
|
214
|
-
helperText: {
|
|
215
|
-
type: String,
|
|
216
|
-
value: ''
|
|
217
|
-
},
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* A placeholder string in addition to the label.
|
|
221
|
-
* @type {string}
|
|
222
|
-
*/
|
|
223
|
-
placeholder: {
|
|
224
|
-
type: String,
|
|
225
|
-
value: ''
|
|
226
|
-
},
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Set to true to prevent user picking a date or typing in the input.
|
|
230
|
-
* @type {boolean}
|
|
231
|
-
*/
|
|
232
|
-
readonly: {
|
|
233
|
-
type: Boolean,
|
|
234
|
-
value: false,
|
|
235
|
-
reflectToAttribute: true
|
|
236
|
-
},
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Set to true if the value is invalid.
|
|
240
|
-
* @type {boolean}
|
|
241
|
-
*/
|
|
242
|
-
invalid: {
|
|
243
|
-
type: Boolean,
|
|
244
|
-
reflectToAttribute: true,
|
|
245
|
-
notify: true,
|
|
246
|
-
value: false
|
|
247
|
-
},
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Minimum time allowed.
|
|
251
|
-
*
|
|
252
|
-
* Supported time formats are in ISO 8601:
|
|
253
|
-
* - `hh:mm`
|
|
254
|
-
* - `hh:mm:ss`
|
|
255
|
-
* - `hh:mm:ss.fff`
|
|
256
|
-
* @type {string}
|
|
257
|
-
*/
|
|
258
|
-
min: {
|
|
259
|
-
type: String,
|
|
260
|
-
value: '00:00:00.000'
|
|
261
|
-
},
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Maximum time allowed.
|
|
265
|
-
*
|
|
266
|
-
* Supported time formats are in ISO 8601:
|
|
267
|
-
* - `hh:mm`
|
|
268
|
-
* - `hh:mm:ss`
|
|
269
|
-
* - `hh:mm:ss.fff`
|
|
270
|
-
* @type {string}
|
|
271
|
-
*/
|
|
272
|
-
max: {
|
|
273
|
-
type: String,
|
|
274
|
-
value: '23:59:59.999'
|
|
275
|
-
},
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Defines the time interval (in seconds) between the items displayed
|
|
279
|
-
* in the time selection box. The default is 1 hour (i.e. `3600`).
|
|
280
|
-
*
|
|
281
|
-
* It also configures the precision of the value string. By default
|
|
282
|
-
* the component formats values as `hh:mm` but setting a step value
|
|
283
|
-
* lower than one minute or one second, format resolution changes to
|
|
284
|
-
* `hh:mm:ss` and `hh:mm:ss.fff` respectively.
|
|
285
|
-
*
|
|
286
|
-
* Unit must be set in seconds, and for correctly configuring intervals
|
|
287
|
-
* in the dropdown, it need to evenly divide a day.
|
|
288
|
-
*
|
|
289
|
-
* Note: it is possible to define step that is dividing an hour in inexact
|
|
290
|
-
* fragments (i.e. 5760 seconds which equals 1 hour 36 minutes), but it is
|
|
291
|
-
* not recommended to use it for better UX experience.
|
|
292
|
-
*/
|
|
293
|
-
step: {
|
|
294
|
-
type: Number
|
|
295
|
-
},
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* Set to true to display the clear icon which clears the input.
|
|
299
|
-
* @attr {boolean} clear-button-visible
|
|
300
|
-
* @type {boolean}
|
|
301
|
-
*/
|
|
302
|
-
clearButtonVisible: {
|
|
303
|
-
type: Boolean,
|
|
304
|
-
value: false
|
|
305
|
-
},
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* Set true to prevent the overlay from opening automatically.
|
|
309
|
-
* @attr {boolean} auto-open-disabled
|
|
310
|
-
*/
|
|
311
|
-
autoOpenDisabled: Boolean,
|
|
312
|
-
|
|
313
|
-
/** @private */
|
|
314
|
-
__dropdownItems: {
|
|
315
|
-
type: Array
|
|
316
|
-
},
|
|
317
|
-
|
|
318
|
-
/**
|
|
319
|
-
* The object used to localize this component.
|
|
320
|
-
* To change the default localization, replace the entire
|
|
321
|
-
* _i18n_ object or just the property you want to modify.
|
|
322
|
-
*
|
|
323
|
-
* The object has the following JSON structure:
|
|
324
|
-
|
|
325
|
-
{
|
|
326
|
-
// A function to format given `Object` as
|
|
327
|
-
// time string. Object is in the format `{ hours: ..., minutes: ..., seconds: ..., milliseconds: ... }`
|
|
328
|
-
formatTime: (time) => {
|
|
329
|
-
// returns a string representation of the given
|
|
330
|
-
// object in `hh` / 'hh:mm' / 'hh:mm:ss' / 'hh:mm:ss.fff' - formats
|
|
331
|
-
},
|
|
332
|
-
|
|
333
|
-
// A function to parse the given text to an `Object` in the format
|
|
334
|
-
// `{ hours: ..., minutes: ..., seconds: ..., milliseconds: ... }`.
|
|
335
|
-
// Must properly parse (at least) text
|
|
336
|
-
// formatted by `formatTime`.
|
|
337
|
-
parseTime: text => {
|
|
338
|
-
// Parses a string in object/string that can be formatted by`formatTime`.
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
// Translation of the time selector icon button title.
|
|
342
|
-
selector: 'Time selector',
|
|
343
|
-
|
|
344
|
-
// Translation of the time selector clear button title.
|
|
345
|
-
clear: 'Clear'
|
|
346
|
-
}
|
|
347
|
-
* @type {!TimePickerI18n}
|
|
348
|
-
*/
|
|
349
|
-
i18n: {
|
|
350
|
-
type: Object,
|
|
351
|
-
value: () => {
|
|
352
|
-
return {
|
|
353
|
-
formatTime: (time) => {
|
|
354
|
-
if (!time) {
|
|
355
|
-
return;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
const pad = (num = 0, fmt = '00') => (fmt + num).substr((fmt + num).length - fmt.length);
|
|
359
|
-
// Always display hour and minute
|
|
360
|
-
let timeString = `${pad(time.hours)}:${pad(time.minutes)}`;
|
|
361
|
-
// Adding second and millisecond depends on resolution
|
|
362
|
-
time.seconds !== undefined && (timeString += `:${pad(time.seconds)}`);
|
|
363
|
-
time.milliseconds !== undefined && (timeString += `.${pad(time.milliseconds, '000')}`);
|
|
364
|
-
return timeString;
|
|
365
|
-
},
|
|
366
|
-
parseTime: (text) => {
|
|
367
|
-
// Parsing with RegExp to ensure correct format
|
|
368
|
-
const MATCH_HOURS = '(\\d|[0-1]\\d|2[0-3])';
|
|
369
|
-
const MATCH_MINUTES = '(\\d|[0-5]\\d)';
|
|
370
|
-
const MATCH_SECONDS = MATCH_MINUTES;
|
|
371
|
-
const MATCH_MILLISECONDS = '(\\d{1,3})';
|
|
372
|
-
const re = new RegExp(
|
|
373
|
-
`^${MATCH_HOURS}(?::${MATCH_MINUTES}(?::${MATCH_SECONDS}(?:\\.${MATCH_MILLISECONDS})?)?)?$`
|
|
374
|
-
);
|
|
375
|
-
const parts = re.exec(text);
|
|
376
|
-
if (parts) {
|
|
377
|
-
// Allows setting the milliseconds with hundreds and tens precision
|
|
378
|
-
if (parts[4]) {
|
|
379
|
-
while (parts[4].length < 3) {
|
|
380
|
-
parts[4] += '0';
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
return { hours: parts[1], minutes: parts[2], seconds: parts[3], milliseconds: parts[4] };
|
|
384
|
-
}
|
|
385
|
-
},
|
|
386
|
-
selector: 'Time selector',
|
|
387
|
-
clear: 'Clear'
|
|
388
|
-
};
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
};
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
static get observers() {
|
|
395
|
-
return ['__updateDropdownItems(i18n.*, min, max, step)'];
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
/** @protected */
|
|
399
|
-
ready() {
|
|
400
|
-
super.ready();
|
|
401
|
-
|
|
402
|
-
// In order to have synchronized invalid property, we need to use the same validate logic.
|
|
403
|
-
this.__inputElement.validate = () => {};
|
|
404
|
-
|
|
405
|
-
// Not using declarative because we receive an event before text-element shadow is ready,
|
|
406
|
-
// thus querySelector in textField.focusElement raises an undefined exception on validate
|
|
407
|
-
this.__dropdownElement.addEventListener('value-changed', (e) => this.__onInputChange(e));
|
|
408
|
-
this.__inputElement.addEventListener('keydown', this.__onKeyDown.bind(this));
|
|
409
|
-
|
|
410
|
-
// Validation listeners
|
|
411
|
-
this.__dropdownElement.addEventListener('change', () => this.validate());
|
|
412
|
-
this.__inputElement.addEventListener('blur', () => this.validate());
|
|
413
|
-
|
|
414
|
-
this.__dropdownElement.addEventListener('change', (e) => {
|
|
415
|
-
// `vaadin-combo-box-light` forwards 'change' event from text-field.
|
|
416
|
-
// So we need to filter out in order to avoid duplicates.
|
|
417
|
-
if (e.composedPath()[0] !== this.__inputElement) {
|
|
418
|
-
this.__dispatchChange();
|
|
419
|
-
}
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
/** @private */
|
|
424
|
-
__validDayDivisor(step) {
|
|
425
|
-
// valid if undefined, or exact divides a day, or has millisecond resolution
|
|
426
|
-
return !step || (24 * 3600) % step === 0 || (step < 1 && ((step % 1) * 1000) % 1 === 0);
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
/** @private */
|
|
430
|
-
__onKeyDown(e) {
|
|
431
|
-
if (this.readonly || this.disabled || this.__dropdownItems.length) {
|
|
432
|
-
return;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
const stepResolution = (this.__validDayDivisor(this.step) && this.step) || 60;
|
|
436
|
-
|
|
437
|
-
if (e.keyCode === 40) {
|
|
438
|
-
this.__onArrowPressWithStep(-stepResolution);
|
|
439
|
-
} else if (e.keyCode === 38) {
|
|
440
|
-
this.__onArrowPressWithStep(stepResolution);
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
/** @private */
|
|
445
|
-
__onArrowPressWithStep(step) {
|
|
446
|
-
const objWithStep = this.__addStep(this.__getMsec(this.__memoValue), step, true);
|
|
447
|
-
this.__memoValue = objWithStep;
|
|
448
|
-
this.__inputElement.value = this.i18n.formatTime(this.__validateTime(objWithStep));
|
|
449
|
-
this.__dispatchChange();
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
/** @private */
|
|
453
|
-
__dispatchChange() {
|
|
454
|
-
this.dispatchEvent(new CustomEvent('change', { bubbles: true }));
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
/**
|
|
458
|
-
* Returning milliseconds from Object in the format `{ hours: ..., minutes: ..., seconds: ..., milliseconds: ... }`
|
|
459
|
-
* @private
|
|
460
|
-
*/
|
|
461
|
-
__getMsec(obj) {
|
|
462
|
-
let result = ((obj && obj.hours) || 0) * 60 * 60 * 1000;
|
|
463
|
-
result += ((obj && obj.minutes) || 0) * 60 * 1000;
|
|
464
|
-
result += ((obj && obj.seconds) || 0) * 1000;
|
|
465
|
-
result += (obj && parseInt(obj.milliseconds)) || 0;
|
|
466
|
-
|
|
467
|
-
return result;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
/**
|
|
471
|
-
* Returning seconds from Object in the format `{ hours: ..., minutes: ..., seconds: ..., milliseconds: ... }`
|
|
472
|
-
* @private
|
|
473
|
-
*/
|
|
474
|
-
__getSec(obj) {
|
|
475
|
-
let result = ((obj && obj.hours) || 0) * 60 * 60;
|
|
476
|
-
result += ((obj && obj.minutes) || 0) * 60;
|
|
477
|
-
result += (obj && obj.seconds) || 0;
|
|
478
|
-
result += (obj && obj.milliseconds / 1000) || 0;
|
|
479
|
-
|
|
480
|
-
return result;
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
/**
|
|
484
|
-
* Returning Object in the format `{ hours: ..., minutes: ..., seconds: ..., milliseconds: ... }`
|
|
485
|
-
* from the result of adding step value in milliseconds to the milliseconds amount.
|
|
486
|
-
* With `precision` parameter rounding the value to the closest step valid interval.
|
|
487
|
-
* @private
|
|
488
|
-
*/
|
|
489
|
-
__addStep(msec, step, precision) {
|
|
490
|
-
// If the time is `00:00` and step changes value downwards, it should be considered as `24:00`
|
|
491
|
-
if (msec === 0 && step < 0) {
|
|
492
|
-
msec = 24 * 60 * 60 * 1000;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
const stepMsec = step * 1000;
|
|
496
|
-
const diffToNext = msec % stepMsec;
|
|
497
|
-
if (stepMsec < 0 && diffToNext && precision) {
|
|
498
|
-
msec -= diffToNext;
|
|
499
|
-
} else if (stepMsec > 0 && diffToNext && precision) {
|
|
500
|
-
msec -= diffToNext - stepMsec;
|
|
501
|
-
} else {
|
|
502
|
-
msec += stepMsec;
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
var hh = Math.floor(msec / 1000 / 60 / 60);
|
|
506
|
-
msec -= hh * 1000 * 60 * 60;
|
|
507
|
-
var mm = Math.floor(msec / 1000 / 60);
|
|
508
|
-
msec -= mm * 1000 * 60;
|
|
509
|
-
var ss = Math.floor(msec / 1000);
|
|
510
|
-
msec -= ss * 1000;
|
|
511
|
-
|
|
512
|
-
return { hours: hh < 24 ? hh : 0, minutes: mm, seconds: ss, milliseconds: msec };
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
/** @private */
|
|
516
|
-
__updateDropdownItems(i8n, min, max, step) {
|
|
517
|
-
const minTimeObj = this.__validateTime(this.__parseISO(min));
|
|
518
|
-
const minSec = this.__getSec(minTimeObj);
|
|
519
|
-
|
|
520
|
-
const maxTimeObj = this.__validateTime(this.__parseISO(max));
|
|
521
|
-
const maxSec = this.__getSec(maxTimeObj);
|
|
522
|
-
|
|
523
|
-
this.__adjustValue(minSec, maxSec, minTimeObj, maxTimeObj);
|
|
524
|
-
|
|
525
|
-
this.__dropdownItems = this.__generateDropdownList(minSec, maxSec, step);
|
|
526
|
-
|
|
527
|
-
if (step !== this.__oldStep) {
|
|
528
|
-
this.__oldStep = step;
|
|
529
|
-
const parsedObj = this.__validateTime(this.__parseISO(this.value));
|
|
530
|
-
this.__updateValue(parsedObj);
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
if (this.value) {
|
|
534
|
-
this.__dropdownElement.value = this.i18n.formatTime(this.i18n.parseTime(this.value));
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
/** @private */
|
|
539
|
-
__generateDropdownList(minSec, maxSec, step) {
|
|
540
|
-
if (step < 15 * 60 || !this.__validDayDivisor(step)) {
|
|
541
|
-
return [];
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
const generatedList = [];
|
|
545
|
-
|
|
546
|
-
// Default step in overlay items is 1 hour
|
|
547
|
-
step = step || 3600;
|
|
548
|
-
|
|
549
|
-
let time = -step + minSec;
|
|
550
|
-
while (time + step >= minSec && time + step <= maxSec) {
|
|
551
|
-
const timeObj = this.__validateTime(this.__addStep(time * 1000, step));
|
|
552
|
-
time += step;
|
|
553
|
-
const formatted = this.i18n.formatTime(timeObj);
|
|
554
|
-
generatedList.push({ label: formatted, value: formatted });
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
return generatedList;
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
/** @private */
|
|
561
|
-
__adjustValue(minSec, maxSec, minTimeObj, maxTimeObj) {
|
|
562
|
-
// Do not change the value if it is empty
|
|
563
|
-
if (!this.__memoValue) {
|
|
564
|
-
return;
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
const valSec = this.__getSec(this.__memoValue);
|
|
568
|
-
|
|
569
|
-
if (valSec < minSec) {
|
|
570
|
-
this.__updateValue(minTimeObj);
|
|
571
|
-
} else if (valSec > maxSec) {
|
|
572
|
-
this.__updateValue(maxTimeObj);
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
/** @private */
|
|
577
|
-
__valueChanged(value, oldValue) {
|
|
578
|
-
const parsedObj = (this.__memoValue = this.__parseISO(value));
|
|
579
|
-
const newValue = this.__formatISO(parsedObj) || '';
|
|
580
|
-
|
|
581
|
-
if (this.value !== '' && this.value !== null && !parsedObj) {
|
|
582
|
-
this.value = oldValue;
|
|
583
|
-
} else if (this.value !== newValue) {
|
|
584
|
-
this.value = newValue;
|
|
585
|
-
} else {
|
|
586
|
-
this.__updateInputValue(parsedObj);
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
/** @private */
|
|
591
|
-
__onInputChange() {
|
|
592
|
-
const parsedObj = this.i18n.parseTime(this.__dropdownElement.value);
|
|
593
|
-
const newValue = this.i18n.formatTime(parsedObj) || '';
|
|
594
|
-
|
|
595
|
-
if (parsedObj) {
|
|
596
|
-
if (this.__dropdownElement.value !== newValue) {
|
|
597
|
-
this.__dropdownElement.value = newValue;
|
|
598
|
-
} else {
|
|
599
|
-
this.__updateValue(parsedObj);
|
|
600
|
-
}
|
|
601
|
-
} else {
|
|
602
|
-
this.value = '';
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
/** @private */
|
|
607
|
-
__updateValue(obj) {
|
|
608
|
-
const timeString = this.__formatISO(this.__validateTime(obj)) || '';
|
|
609
|
-
this.value = timeString;
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
/** @private */
|
|
613
|
-
__updateInputValue(obj) {
|
|
614
|
-
const timeString = this.i18n.formatTime(this.__validateTime(obj)) || '';
|
|
615
|
-
this.__dropdownElement.value = timeString;
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
/** @private */
|
|
619
|
-
__validateTime(timeObject) {
|
|
620
|
-
if (timeObject) {
|
|
621
|
-
timeObject.hours = parseInt(timeObject.hours);
|
|
622
|
-
timeObject.minutes = parseInt(timeObject.minutes || 0);
|
|
623
|
-
timeObject.seconds = this.__stepSegment < 3 ? undefined : parseInt(timeObject.seconds || 0);
|
|
624
|
-
timeObject.milliseconds = this.__stepSegment < 4 ? undefined : parseInt(timeObject.milliseconds || 0);
|
|
625
|
-
}
|
|
626
|
-
return timeObject;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
/** @private */
|
|
630
|
-
get __stepSegment() {
|
|
631
|
-
if (this.step % 3600 === 0) {
|
|
632
|
-
// Accept hours
|
|
633
|
-
return 1;
|
|
634
|
-
} else if (this.step % 60 === 0 || !this.step) {
|
|
635
|
-
// Accept minutes
|
|
636
|
-
return 2;
|
|
637
|
-
} else if (this.step % 1 === 0) {
|
|
638
|
-
// Accept seconds
|
|
639
|
-
return 3;
|
|
640
|
-
} else if (this.step < 1) {
|
|
641
|
-
// Accept milliseconds
|
|
642
|
-
return 4;
|
|
643
|
-
}
|
|
644
|
-
return undefined;
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
/** @private */
|
|
648
|
-
__formatISO(time) {
|
|
649
|
-
// The default i18n formatter implementation is ISO 8601 compliant
|
|
650
|
-
return TimePickerElement.properties.i18n.value().formatTime(time);
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
/** @private */
|
|
654
|
-
__parseISO(text) {
|
|
655
|
-
// The default i18n parser implementation is ISO 8601 compliant
|
|
656
|
-
return TimePickerElement.properties.i18n.value().parseTime(text);
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
/** @protected */
|
|
660
|
-
_getInputElement() {
|
|
661
|
-
return this.shadowRoot.querySelector('vaadin-time-picker-text-field');
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
/** @private */
|
|
665
|
-
get __inputElement() {
|
|
666
|
-
return this.__memoInput || (this.__memoInput = this._getInputElement());
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
/** @private */
|
|
670
|
-
get __dropdownElement() {
|
|
671
|
-
return this.__memoDropdown || (this.__memoDropdown = this.shadowRoot.querySelector('vaadin-combo-box-light'));
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
/**
|
|
675
|
-
* Focusable element used by vaadin-control-state-mixin
|
|
676
|
-
* @return {!HTMLElement}
|
|
677
|
-
* @protected
|
|
678
|
-
*/
|
|
679
|
-
get focusElement() {
|
|
680
|
-
return this.__inputElement;
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
/**
|
|
684
|
-
* Returns true if `value` is valid, and sets the `invalid` flag appropriately.
|
|
685
|
-
*
|
|
686
|
-
* @return {boolean} True if the value is valid and sets the `invalid` flag appropriately
|
|
687
|
-
*/
|
|
688
|
-
validate() {
|
|
689
|
-
return !(this.invalid = !this.checkValidity());
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
/**
|
|
693
|
-
* Returns true if `time` satisfies the `min` and `max` constraints (if any).
|
|
694
|
-
*
|
|
695
|
-
* @param {!TimePickerTime} time Value to check against constraints
|
|
696
|
-
* @return {boolean} True if `time` satisfies the constraints
|
|
697
|
-
* @protected
|
|
698
|
-
*/
|
|
699
|
-
_timeAllowed(time) {
|
|
700
|
-
const parsedMin = this.i18n.parseTime(this.min);
|
|
701
|
-
const parsedMax = this.i18n.parseTime(this.max);
|
|
702
|
-
|
|
703
|
-
return (
|
|
704
|
-
(!this.__getMsec(parsedMin) || this.__getMsec(time) >= this.__getMsec(parsedMin)) &&
|
|
705
|
-
(!this.__getMsec(parsedMax) || this.__getMsec(time) <= this.__getMsec(parsedMax))
|
|
706
|
-
);
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
/**
|
|
710
|
-
* Returns true if the current input value satisfies all constraints (if any)
|
|
711
|
-
*
|
|
712
|
-
* You can override the `checkValidity` method for custom validations.
|
|
713
|
-
*
|
|
714
|
-
* @return {boolean} True if the value is valid
|
|
715
|
-
*/
|
|
716
|
-
checkValidity() {
|
|
717
|
-
return !!(
|
|
718
|
-
this.__inputElement.focusElement.checkValidity() &&
|
|
719
|
-
(!this.value || this._timeAllowed(this.i18n.parseTime(this.value))) &&
|
|
720
|
-
(!this.__dropdownElement.value || this.i18n.parseTime(this.__dropdownElement.value))
|
|
721
|
-
);
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
/**
|
|
725
|
-
* Fired when the user commits a value change.
|
|
726
|
-
*
|
|
727
|
-
* @event change
|
|
728
|
-
*/
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
customElements.define(TimePickerElement.is, TimePickerElement);
|
|
732
|
-
|
|
733
|
-
export { TimePickerElement };
|
|
13
|
+
export const TimePickerElement = TimePicker;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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 '@vaadin/time-picker/theme/lumo/vaadin-time-picker.js';
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
|
|
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 '@vaadin/time-picker/theme/material/vaadin-time-picker.js';
|
package/vaadin-time-picker.d.ts
CHANGED
package/src/interfaces.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
export interface TimePickerTime {
|
|
2
|
-
hours: string | number;
|
|
3
|
-
minutes: string | number;
|
|
4
|
-
seconds?: string | number;
|
|
5
|
-
milliseconds?: string | number;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export interface TimePickerI18n {
|
|
9
|
-
parseTime: (time: string) => TimePickerTime | undefined;
|
|
10
|
-
formatTime: (time: TimePickerTime) => string;
|
|
11
|
-
clear: string;
|
|
12
|
-
selector: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Fired when the `invalid` property changes.
|
|
17
|
-
*/
|
|
18
|
-
export type TimePickerInvalidChangedEvent = CustomEvent<{ value: boolean }>;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Fired when the `value` property changes.
|
|
22
|
-
*/
|
|
23
|
-
export type TimePickerValueChangedEvent = CustomEvent<{ value: string }>;
|
|
24
|
-
|
|
25
|
-
export interface TimePickerElementEventMap {
|
|
26
|
-
'invalid-changed': TimePickerInvalidChangedEvent;
|
|
27
|
-
|
|
28
|
-
'value-changed': TimePickerValueChangedEvent;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface TimePickerEventMap extends HTMLElementEventMap, TimePickerElementEventMap {}
|
|
@@ -1,41 +0,0 @@
|
|
|
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 { TextFieldElement } from '@vaadin/vaadin-text-field/src/vaadin-text-field.js';
|
|
7
|
-
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
|
|
8
|
-
|
|
9
|
-
registerStyles(
|
|
10
|
-
'vaadin-time-picker-text-field',
|
|
11
|
-
css`
|
|
12
|
-
:host([dir='rtl']) [part='input-field'] {
|
|
13
|
-
direction: ltr;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
:host([dir='rtl']) [part='value']::placeholder {
|
|
17
|
-
direction: rtl;
|
|
18
|
-
text-align: left;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
:host([dir='rtl']) [part='input-field'] ::slotted(input)::placeholder {
|
|
22
|
-
direction: rtl;
|
|
23
|
-
text-align: left;
|
|
24
|
-
}
|
|
25
|
-
`,
|
|
26
|
-
{ moduleId: 'vaadin-time-picker-text-field-styles' }
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* An element used internally by `<vaadin-time-picker>`. Not intended to be used separately.
|
|
31
|
-
*
|
|
32
|
-
* @extends TextFieldElement
|
|
33
|
-
* @protected
|
|
34
|
-
*/
|
|
35
|
-
class TimePickerTextFieldElement extends TextFieldElement {
|
|
36
|
-
static get is() {
|
|
37
|
-
return 'vaadin-time-picker-text-field';
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
customElements.define(TimePickerTextFieldElement.is, TimePickerTextFieldElement);
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import '@vaadin/vaadin-combo-box/theme/lumo/vaadin-combo-box-light.js';
|
|
2
|
-
import { fieldButton } from '@vaadin/vaadin-lumo-styles/mixins/field-button.js';
|
|
3
|
-
import '@vaadin/vaadin-lumo-styles/font-icons.js';
|
|
4
|
-
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
|
|
5
|
-
|
|
6
|
-
const timePicker = css`
|
|
7
|
-
[part~='toggle-button']::before {
|
|
8
|
-
content: var(--lumo-icons-clock);
|
|
9
|
-
}
|
|
10
|
-
`;
|
|
11
|
-
|
|
12
|
-
registerStyles('vaadin-time-picker', [fieldButton, timePicker], { moduleId: 'lumo-time-picker' });
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import '@vaadin/vaadin-text-field/theme/lumo/vaadin-text-field.js';
|
|
2
|
-
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
|
|
3
|
-
|
|
4
|
-
registerStyles(
|
|
5
|
-
'vaadin-time-picker-text-field',
|
|
6
|
-
css`
|
|
7
|
-
:host([dir='rtl']) [part='value']:placeholder-shown,
|
|
8
|
-
:host([dir='rtl']) [part='input-field'] ::slotted(input:placeholder-shown) {
|
|
9
|
-
--_lumo-text-field-overflow-mask-image: none;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
:host([dir='rtl']) [part='value'],
|
|
13
|
-
:host([dir='rtl']) [part='input-field'] ::slotted(input) {
|
|
14
|
-
--_lumo-text-field-overflow-mask-image: linear-gradient(to left, transparent, #000 1.25em);
|
|
15
|
-
}
|
|
16
|
-
`,
|
|
17
|
-
{ moduleId: 'lumo-time-picker-text-field' }
|
|
18
|
-
);
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import '@vaadin/vaadin-combo-box/theme/material/vaadin-combo-box-light.js';
|
|
2
|
-
import '@vaadin/vaadin-text-field/theme/material/vaadin-text-field.js';
|
|
3
|
-
import { fieldButton } from '@vaadin/vaadin-material-styles/mixins/field-button.js';
|
|
4
|
-
import '@vaadin/vaadin-material-styles/font-icons.js';
|
|
5
|
-
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
|
|
6
|
-
|
|
7
|
-
const timePicker = css`
|
|
8
|
-
[part~='toggle-button']::before {
|
|
9
|
-
content: var(--material-icons-clock);
|
|
10
|
-
}
|
|
11
|
-
`;
|
|
12
|
-
|
|
13
|
-
registerStyles('vaadin-time-picker', [fieldButton, timePicker], {
|
|
14
|
-
moduleId: 'material-time-picker'
|
|
15
|
-
});
|