@vaadin/time-picker 25.0.0-alpha2 → 25.0.0-alpha21

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.
@@ -3,6 +3,8 @@
3
3
  * Copyright (c) 2018 - 2025 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
+ import { ComboBoxBaseMixin } from '@vaadin/combo-box/src/vaadin-combo-box-base-mixin.js';
7
+ import { I18nMixin } from '@vaadin/component-base/src/i18n-mixin.js';
6
8
  import { TooltipController } from '@vaadin/component-base/src/tooltip-controller.js';
7
9
  import { InputControlMixin } from '@vaadin/field-base/src/input-control-mixin.js';
8
10
  import { InputController } from '@vaadin/field-base/src/input-controller.js';
@@ -22,11 +24,16 @@ const MAX_ALLOWED_TIME = '23:59:59.999';
22
24
  * A mixin providing common time-picker functionality.
23
25
  *
24
26
  * @polymerMixin
27
+ * @mixes ComboBoxBaseMixin
28
+ * @mixes I18nMixin
25
29
  * @mixes InputControlMixin
26
30
  * @mixes PatternMixin
27
31
  */
28
32
  export const TimePickerMixin = (superClass) =>
29
- class TimePickerMixinClass extends PatternMixin(InputControlMixin(superClass)) {
33
+ class TimePickerMixinClass extends I18nMixin(
34
+ timePickerI18nDefaults,
35
+ PatternMixin(ComboBoxBaseMixin(InputControlMixin(superClass))),
36
+ ) {
30
37
  static get properties() {
31
38
  return {
32
39
  /**
@@ -45,17 +52,6 @@ export const TimePickerMixin = (superClass) =>
45
52
  sync: true,
46
53
  },
47
54
 
48
- /**
49
- * True if the dropdown is open, false otherwise.
50
- */
51
- opened: {
52
- type: Boolean,
53
- notify: true,
54
- value: false,
55
- reflectToAttribute: true,
56
- sync: true,
57
- },
58
-
59
55
  /**
60
56
  * Minimum time allowed.
61
57
  *
@@ -107,61 +103,6 @@ export const TimePickerMixin = (superClass) =>
107
103
  sync: true,
108
104
  },
109
105
 
110
- /**
111
- * Set true to prevent the overlay from opening automatically.
112
- * @attr {boolean} auto-open-disabled
113
- */
114
- autoOpenDisabled: {
115
- type: Boolean,
116
- sync: true,
117
- },
118
-
119
- /**
120
- * A space-delimited list of CSS class names to set on the overlay element.
121
- *
122
- * @attr {string} overlay-class
123
- */
124
- overlayClass: {
125
- type: String,
126
- },
127
-
128
- /**
129
- * The object used to localize this component.
130
- * To change the default localization, replace the entire
131
- * _i18n_ object or just the property you want to modify.
132
- *
133
- * The object has the following JSON structure:
134
- *
135
- * ```
136
- * {
137
- * // A function to format given `Object` as
138
- * // time string. Object is in the format `{ hours: ..., minutes: ..., seconds: ..., milliseconds: ... }`
139
- * formatTime: (time) => {
140
- * // returns a string representation of the given
141
- * // object in `hh` / 'hh:mm' / 'hh:mm:ss' / 'hh:mm:ss.fff' - formats
142
- * },
143
- *
144
- * // A function to parse the given text to an `Object` in the format
145
- * // `{ hours: ..., minutes: ..., seconds: ..., milliseconds: ... }`.
146
- * // Must properly parse (at least) text
147
- * // formatted by `formatTime`.
148
- * parseTime: text => {
149
- * // Parses a string in object/string that can be formatted by`formatTime`.
150
- * }
151
- * }
152
- * ```
153
- *
154
- * Both `formatTime` and `parseTime` need to be implemented
155
- * to ensure the component works properly.
156
- *
157
- * @type {!TimePickerI18n}
158
- */
159
- i18n: {
160
- type: Object,
161
- sync: true,
162
- value: () => ({ ...timePickerI18nDefaults }),
163
- },
164
-
165
106
  /** @private */
166
107
  _comboBoxValue: {
167
108
  type: String,
@@ -169,12 +110,6 @@ export const TimePickerMixin = (superClass) =>
169
110
  observer: '__comboBoxValueChanged',
170
111
  },
171
112
 
172
- /** @private */
173
- __dropdownItems: {
174
- type: Array,
175
- sync: true,
176
- },
177
-
178
113
  /** @private */
179
114
  _inputContainer: {
180
115
  type: Object,
@@ -184,8 +119,10 @@ export const TimePickerMixin = (superClass) =>
184
119
 
185
120
  static get observers() {
186
121
  return [
187
- '__updateAriaAttributes(__dropdownItems, opened, inputElement)',
188
- '__updateDropdownItems(i18n, min, max, step)',
122
+ '_openedOrItemsChanged(opened, _dropdownItems)',
123
+ '_updateScroller(opened, _dropdownItems, _focusedIndex, _theme)',
124
+ '__updateAriaAttributes(_dropdownItems, opened, inputElement)',
125
+ '__updateDropdownItems(__effectiveI18n, min, max, step)',
189
126
  ];
190
127
  }
191
128
 
@@ -193,6 +130,15 @@ export const TimePickerMixin = (superClass) =>
193
130
  return [...super.constraints, 'min', 'max'];
194
131
  }
195
132
 
133
+ /**
134
+ * Tag name prefix used by `ComboBoxBaseMixin` for scroller and items.
135
+ * @protected
136
+ * @return {string}
137
+ */
138
+ get _tagNamePrefix() {
139
+ return 'vaadin-time-picker';
140
+ }
141
+
196
142
  /**
197
143
  * Used by `ClearButtonMixin` as a reference to the clear button element.
198
144
  * @protected
@@ -202,6 +148,45 @@ export const TimePickerMixin = (superClass) =>
202
148
  return this.$.clearButton;
203
149
  }
204
150
 
151
+ /**
152
+ * The object used to localize this component. To change the default
153
+ * localization, replace this with an object that provides both the
154
+ * time parsing and formatting functions.
155
+ *
156
+ * The object has the following JSON structure:
157
+ *
158
+ * ```js
159
+ * {
160
+ * // A function to format given `Object` as
161
+ * // time string. Object is in the format `{ hours: ..., minutes: ..., seconds: ..., milliseconds: ... }`
162
+ * formatTime: (time) => {
163
+ * // returns a string representation of the given
164
+ * // object in `hh` / 'hh:mm' / 'hh:mm:ss' / 'hh:mm:ss.fff' - formats
165
+ * },
166
+ *
167
+ * // A function to parse the given text to an `Object` in the format
168
+ * // `{ hours: ..., minutes: ..., seconds: ..., milliseconds: ... }`.
169
+ * // Must properly parse (at least) text
170
+ * // formatted by `formatTime`.
171
+ * parseTime: text => {
172
+ * // Parses a string in object/string that can be formatted by`formatTime`.
173
+ * }
174
+ * }
175
+ * ```
176
+ *
177
+ * NOTE: `formatTime` and `parseTime` must be implemented in a
178
+ * compatible manner to ensure the component works properly.
179
+ *
180
+ * @return {!TimePickerI18n}
181
+ */
182
+ get i18n() {
183
+ return super.i18n;
184
+ }
185
+
186
+ set i18n(value) {
187
+ super.i18n = value;
188
+ }
189
+
205
190
  /**
206
191
  * The input element's value when it cannot be parsed as a time, and an empty string otherwise.
207
192
  *
@@ -209,7 +194,7 @@ export const TimePickerMixin = (superClass) =>
209
194
  * @return {string}
210
195
  */
211
196
  get __unparsableValue() {
212
- if (this._inputElementValue && !this.i18n.parseTime(this._inputElementValue)) {
197
+ if (this._inputElementValue && !this.__effectiveI18n.parseTime(this._inputElementValue)) {
213
198
  return this._inputElementValue;
214
199
  }
215
200
 
@@ -239,6 +224,7 @@ export const TimePickerMixin = (superClass) =>
239
224
  );
240
225
  this.addController(new LabelledInputController(this.inputElement, this._labelController));
241
226
  this._inputContainer = this.shadowRoot.querySelector('[part~="input-field"]');
227
+ this._toggleElement = this.$.toggleButton;
242
228
 
243
229
  this._tooltipController = new TooltipController(this);
244
230
  this._tooltipController.setShouldShow((timePicker) => !timePicker.opened);
@@ -247,47 +233,136 @@ export const TimePickerMixin = (superClass) =>
247
233
  this.addController(this._tooltipController);
248
234
  }
249
235
 
236
+ /** @protected */
237
+ updated(props) {
238
+ super.updated(props);
239
+
240
+ // Update selected item in the scroller
241
+ if (props.has('_comboBoxValue') && this._dropdownItems) {
242
+ this._scroller.selectedItem = this._dropdownItems.find((item) => item.value === this._comboBoxValue);
243
+ }
244
+ }
245
+
250
246
  /**
251
- * Override method inherited from `InputMixin` to forward the input to combo-box.
247
+ * Returns true if the current input value satisfies all constraints (if any).
248
+ * You can override this method for custom validations.
249
+ *
250
+ * @return {boolean} True if the value is valid
251
+ */
252
+ checkValidity() {
253
+ return !!(
254
+ this.inputElement.checkValidity() &&
255
+ (!this.value || this._timeAllowed(this.__effectiveI18n.parseTime(this.value))) &&
256
+ (!this._comboBoxValue || this.__effectiveI18n.parseTime(this._comboBoxValue))
257
+ );
258
+ }
259
+
260
+ /**
261
+ * Override method from `ComboBoxBaseMixin` to handle item label path.
252
262
  * @protected
253
263
  * @override
254
264
  */
255
- _inputElementChanged(input) {
256
- super._inputElementChanged(input);
265
+ _getItemLabel(item) {
266
+ return item ? item.label : '';
267
+ }
257
268
 
258
- if (input) {
259
- this.$.comboBox._setInputElement(input);
269
+ /** @private */
270
+ _updateScroller(opened, items, focusedIndex, theme) {
271
+ if (opened) {
272
+ this._scroller.style.maxHeight =
273
+ getComputedStyle(this).getPropertyValue(`--${this._tagNamePrefix}-overlay-max-height`) || '65vh';
260
274
  }
275
+
276
+ this._scroller.setProperties({
277
+ items: opened ? items : [],
278
+ opened,
279
+ focusedIndex,
280
+ theme,
281
+ });
282
+ }
283
+
284
+ /** @private */
285
+ _openedOrItemsChanged(opened, items) {
286
+ // Close the overlay if there are no items to display.
287
+ this._overlayOpened = opened && !!(items && items.length);
288
+ }
289
+
290
+ /**
291
+ * Override method from `ComboBoxBaseMixin` to commit value on overlay closing.
292
+ * @protected
293
+ * @override
294
+ */
295
+ _onClosed() {
296
+ this._commitValue();
297
+ }
298
+
299
+ /**
300
+ * Override method from `ComboBoxBaseMixin` to handle Escape pres..
301
+ * @protected
302
+ * @override
303
+ */
304
+ _onEscapeCancel() {
305
+ this._inputElementValue = this._comboBoxValue;
306
+ this._closeOrCommit();
307
+ }
308
+
309
+ /**
310
+ * Override method from `ComboBoxBaseMixin` to implement clearing logic.
311
+ * @protected
312
+ * @override
313
+ */
314
+ _onClearAction() {
315
+ this._comboBoxValue = '';
316
+ this._inputElementValue = '';
317
+
318
+ this.__commitValueChange();
261
319
  }
262
320
 
263
321
  /**
264
- * Opens the dropdown list.
322
+ * Override method from `ComboBoxBaseMixin` to implement value commit logic.
323
+ * @protected
324
+ * @override
265
325
  */
266
- open() {
267
- if (!this.disabled && !this.readonly) {
268
- this.opened = true;
326
+ _commitValue() {
327
+ if (this._focusedIndex > -1) {
328
+ // Commit value based on focused index
329
+ const focusedItem = this._dropdownItems[this._focusedIndex];
330
+ const itemValue = this._getItemLabel(focusedItem);
331
+ this._inputElementValue = itemValue;
332
+ this._comboBoxValue = itemValue;
333
+ this._focusedIndex = -1;
334
+ } else if (this._inputElementValue === '' || this._inputElementValue === undefined) {
335
+ this._comboBoxValue = '';
336
+ } else {
337
+ this._comboBoxValue = this._inputElementValue;
269
338
  }
339
+
340
+ this.__commitValueChange();
341
+
342
+ this._clearSelectionRange();
270
343
  }
271
344
 
272
345
  /**
273
- * Closes the dropdown list.
346
+ * Override method from `ComboBoxBaseMixin` to handle loading.
347
+ * @protected
348
+ * @override
274
349
  */
275
- close() {
276
- this.opened = false;
350
+ _closeOrCommit() {
351
+ if (!this.opened) {
352
+ this._commitValue();
353
+ } else {
354
+ this.close();
355
+ }
277
356
  }
278
357
 
279
358
  /**
280
- * Returns true if the current input value satisfies all constraints (if any).
281
- * You can override this method for custom validations.
282
- *
283
- * @return {boolean} True if the value is valid
359
+ * Override method from `ComboBoxBaseMixin` to handle reverting value.
360
+ * @protected
361
+ * @override
284
362
  */
285
- checkValidity() {
286
- return !!(
287
- this.inputElement.checkValidity() &&
288
- (!this.value || this._timeAllowed(this.i18n.parseTime(this.value))) &&
289
- (!this._comboBoxValue || this.i18n.parseTime(this._comboBoxValue))
290
- );
363
+ _revertInputValue() {
364
+ this._inputElementValue = this._comboBoxValue;
365
+ this._clearSelectionRange();
291
366
  }
292
367
 
293
368
  /**
@@ -321,7 +396,7 @@ export const TimePickerMixin = (superClass) =>
321
396
  _onKeyDown(e) {
322
397
  super._onKeyDown(e);
323
398
 
324
- if (this.readonly || this.disabled || this.__dropdownItems.length) {
399
+ if (this.readonly || this.disabled || this._dropdownItems.length) {
325
400
  return;
326
401
  }
327
402
 
@@ -334,17 +409,6 @@ export const TimePickerMixin = (superClass) =>
334
409
  }
335
410
  }
336
411
 
337
- /**
338
- * Override an event listener from `KeyboardMixin`.
339
- * Do not call `super` in order to override clear
340
- * button logic defined in `InputControlMixin`.
341
- * @param {Event} event
342
- * @protected
343
- */
344
- _onEscape() {
345
- // Do nothing, the internal combo-box handles Escape.
346
- }
347
-
348
412
  /** @private */
349
413
  __onArrowPressWithStep(step) {
350
414
  const objWithStep = this.__addStep(this.__getMsec(this.__memoValue), step, true);
@@ -354,7 +418,7 @@ export const TimePickerMixin = (superClass) =>
354
418
  // observer where the value can be parsed again, so we set
355
419
  // this flag to ensure it does not alter the value.
356
420
  this.__useMemo = true;
357
- this._comboBoxValue = this.i18n.formatTime(objWithStep);
421
+ this._comboBoxValue = this.__effectiveI18n.formatTime(objWithStep);
358
422
  this.__useMemo = false;
359
423
 
360
424
  this.__commitValueChange();
@@ -451,14 +515,14 @@ export const TimePickerMixin = (superClass) =>
451
515
  }
452
516
 
453
517
  /** @private */
454
- __updateDropdownItems(i18n, min, max, step) {
518
+ __updateDropdownItems(effectiveI18n, min, max, step) {
455
519
  const minTimeObj = validateTime(parseISOTime(min || MIN_ALLOWED_TIME), step);
456
520
  const minSec = this.__getSec(minTimeObj);
457
521
 
458
522
  const maxTimeObj = validateTime(parseISOTime(max || MAX_ALLOWED_TIME), step);
459
523
  const maxSec = this.__getSec(maxTimeObj);
460
524
 
461
- this.__dropdownItems = this.__generateDropdownList(minSec, maxSec, step);
525
+ this._dropdownItems = this.__generateDropdownList(minSec, maxSec, step);
462
526
 
463
527
  if (step !== this.__oldStep) {
464
528
  this.__oldStep = step;
@@ -467,7 +531,7 @@ export const TimePickerMixin = (superClass) =>
467
531
  }
468
532
 
469
533
  if (this.value) {
470
- this._comboBoxValue = i18n.formatTime(i18n.parseTime(this.value));
534
+ this._comboBoxValue = effectiveI18n.formatTime(effectiveI18n.parseTime(this.value));
471
535
  }
472
536
  }
473
537
 
@@ -503,7 +567,7 @@ export const TimePickerMixin = (superClass) =>
503
567
  while (time + step >= minSec && time + step <= maxSec) {
504
568
  const timeObj = validateTime(this.__addStep(time * 1000, step), step);
505
569
  time += step;
506
- const formatted = this.i18n.formatTime(timeObj);
570
+ const formatted = this.__effectiveI18n.formatTime(timeObj);
507
571
  generatedList.push({ label: formatted, value: formatted });
508
572
  }
509
573
 
@@ -549,8 +613,8 @@ export const TimePickerMixin = (superClass) =>
549
613
  return;
550
614
  }
551
615
 
552
- const parsedObj = this.__useMemo ? this.__memoValue : this.i18n.parseTime(value);
553
- const newValue = this.i18n.formatTime(parsedObj) || '';
616
+ const parsedObj = this.__useMemo ? this.__memoValue : this.__effectiveI18n.parseTime(value);
617
+ const newValue = this.__effectiveI18n.formatTime(parsedObj) || '';
554
618
 
555
619
  if (parsedObj) {
556
620
  if (value !== newValue) {
@@ -574,12 +638,6 @@ export const TimePickerMixin = (superClass) =>
574
638
  }
575
639
  }
576
640
 
577
- /** @private */
578
- __onComboBoxChange(event) {
579
- event.stopPropagation();
580
- this.__commitValueChange();
581
- }
582
-
583
641
  /** @private */
584
642
  __updateValue(obj) {
585
643
  const timeString = formatISOTime(validateTime(obj, this.step)) || '';
@@ -593,7 +651,8 @@ export const TimePickerMixin = (superClass) =>
593
651
 
594
652
  /** @private */
595
653
  __updateInputValue(obj) {
596
- const timeString = this.i18n.formatTime(validateTime(obj, this.step)) || '';
654
+ const timeString = this.__effectiveI18n.formatTime(validateTime(obj, this.step)) || '';
655
+ this._inputElementValue = timeString;
597
656
  this._comboBoxValue = timeString;
598
657
  }
599
658
 
@@ -605,8 +664,8 @@ export const TimePickerMixin = (superClass) =>
605
664
  * @protected
606
665
  */
607
666
  _timeAllowed(time) {
608
- const parsedMin = this.i18n.parseTime(this.min || MIN_ALLOWED_TIME);
609
- const parsedMax = this.i18n.parseTime(this.max || MAX_ALLOWED_TIME);
667
+ const parsedMin = this.__effectiveI18n.parseTime(this.min || MIN_ALLOWED_TIME);
668
+ const parsedMax = this.__effectiveI18n.parseTime(this.max || MAX_ALLOWED_TIME);
610
669
 
611
670
  return (
612
671
  (!this.__getMsec(parsedMin) || this.__getMsec(time) >= this.__getMsec(parsedMin)) &&
@@ -615,22 +674,44 @@ export const TimePickerMixin = (superClass) =>
615
674
  }
616
675
 
617
676
  /**
618
- * Override method inherited from `InputControlMixin`.
677
+ * Override method from `ComboBoxBaseMixin` to deselect
678
+ * dropdown item by requesting content update on clear.
679
+ * @param {Event} event
619
680
  * @protected
620
681
  */
621
- _onClearButtonClick() {}
682
+ _onClearButtonClick(event) {
683
+ event.stopPropagation();
684
+ super._onClearButtonClick(event);
685
+
686
+ if (this.opened) {
687
+ this._scroller.requestContentUpdate();
688
+ }
689
+ }
622
690
 
623
691
  /**
624
- * Override method inherited from `InputConstraintsMixin`.
692
+ * @param {Event} event
625
693
  * @protected
626
694
  */
627
- _onChange() {}
695
+ _onHostClick(event) {
696
+ const path = event.composedPath();
697
+
698
+ // Open dropdown only when clicking on the label or input field
699
+ if (path.includes(this._labelNode) || path.includes(this._inputContainer)) {
700
+ super._onHostClick(event);
701
+ }
702
+ }
628
703
 
629
704
  /**
630
- * Override method inherited from `InputMixin`.
705
+ * Override an event listener from `InputMixin`.
706
+ * @param {!Event} event
631
707
  * @protected
708
+ * @override
632
709
  */
633
- _onInput() {}
710
+ _onChange(event) {
711
+ // Suppress the native change event fired on the native input.
712
+ // We use `__commitValueChange` to fire a custom event.
713
+ event.stopPropagation();
714
+ }
634
715
 
635
716
  /**
636
717
  * Fired when the user commits a value change.
@@ -8,10 +8,11 @@ import { ComboBoxOverlayMixin } from '@vaadin/combo-box/src/vaadin-combo-box-ove
8
8
  import { defineCustomElement } from '@vaadin/component-base/src/define.js';
9
9
  import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
10
10
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
11
+ import { overlayStyles } from '@vaadin/overlay/src/styles/vaadin-overlay-base-styles.js';
11
12
  import { OverlayMixin } from '@vaadin/overlay/src/vaadin-overlay-mixin.js';
12
- import { overlayStyles } from '@vaadin/overlay/src/vaadin-overlay-styles.js';
13
+ import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
13
14
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
14
- import { timePickerOverlayStyles } from './styles/vaadin-time-picker-overlay-core-styles.js';
15
+ import { timePickerOverlayStyles } from './styles/vaadin-time-picker-overlay-base-styles.js';
15
16
 
16
17
  /**
17
18
  * An element used internally by `<vaadin-time-picker>`. Not intended to be used separately.
@@ -24,7 +25,7 @@ import { timePickerOverlayStyles } from './styles/vaadin-time-picker-overlay-cor
24
25
  * @private
25
26
  */
26
27
  export class TimePickerOverlay extends ComboBoxOverlayMixin(
27
- OverlayMixin(DirMixin(ThemableMixin(PolylitMixin(LitElement)))),
28
+ OverlayMixin(DirMixin(ThemableMixin(PolylitMixin(LumoInjectionMixin(LitElement))))),
28
29
  ) {
29
30
  static get is() {
30
31
  return 'vaadin-time-picker-overlay';
@@ -37,7 +38,6 @@ export class TimePickerOverlay extends ComboBoxOverlayMixin(
37
38
  /** @protected */
38
39
  render() {
39
40
  return html`
40
- <div id="backdrop" part="backdrop" hidden></div>
41
41
  <div part="overlay" id="overlay">
42
42
  <div part="content" id="content">
43
43
  <slot></slot>
@@ -7,7 +7,7 @@ import { html, LitElement } from 'lit';
7
7
  import { ComboBoxScrollerMixin } from '@vaadin/combo-box/src/vaadin-combo-box-scroller-mixin.js';
8
8
  import { defineCustomElement } from '@vaadin/component-base/src/define.js';
9
9
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
10
- import { timePickerScrollerStyles } from './styles/vaadin-time-picker-scroller-core-styles.js';
10
+ import { timePickerScrollerStyles } from './styles/vaadin-time-picker-scroller-base-styles.js';
11
11
 
12
12
  /**
13
13
  * An element used internally by `<vaadin-time-picker>`. Not intended to be used separately.
@@ -73,33 +73,43 @@ export interface TimePickerEventMap extends HTMLElementEventMap, TimePickerCusto
73
73
  * `--vaadin-time-picker-overlay-width` | Width of the overlay | `auto`
74
74
  * `--vaadin-time-picker-overlay-max-height`| Max height of the overlay | `65vh`
75
75
  *
76
- * `<vaadin-time-picker>` provides the same set of shadow DOM parts and state attributes as `<vaadin-text-field>`.
77
- * See [`<vaadin-text-field>`](#/elements/vaadin-text-field) for the styling documentation.
78
- *
79
- * In addition to `<vaadin-text-field>` parts, the following parts are available for theming:
80
- *
81
- * Part name | Description
82
- * ----------------|----------------
83
- * `toggle-button` | The toggle button
84
- *
85
- * In addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:
86
- *
87
- * Attribute | Description
88
- * ----------|------------------------------------------
89
- * `opened` | Set when the time-picker dropdown is open
76
+ * The following shadow DOM parts are available for styling:
77
+ *
78
+ * Part name | Description
79
+ * ---------------------|----------------
80
+ * `label` | The label element
81
+ * `input-field` | The element that wraps prefix, value and buttons
82
+ * `field-button` | Set on both clear and toggle buttons
83
+ * `clear-button` | The clear button
84
+ * `error-message` | The error message element
85
+ * `helper-text` | The helper text element wrapper
86
+ * `required-indicator` | The `required` state indicator element
87
+ * `toggle-button` | The toggle button
88
+ * `overlay` | The overlay container
89
+ * `content` | The overlay content
90
+ *
91
+ * The following state attributes are available for styling:
92
+ *
93
+ * Attribute | Description
94
+ * ---------------------|---------------------------------
95
+ * `disabled` | Set when the element is disabled
96
+ * `has-value` | Set when the element has a value
97
+ * `has-label` | Set when the element has a label
98
+ * `has-helper` | Set when the element has helper text or slot
99
+ * `has-error-message` | Set when the element has an error message
100
+ * `has-tooltip` | Set when the element has a slotted tooltip
101
+ * `invalid` | Set when the element is invalid
102
+ * `focused` | Set when the element is focused
103
+ * `focus-ring` | Set when the element is keyboard focused
104
+ * `readonly` | Set when the element is readonly
105
+ * `opened` | Set when the overlay is opened
90
106
  *
91
107
  * ### Internal components
92
108
  *
93
109
  * In addition to `<vaadin-time-picker>` itself, the following internal
94
110
  * components are themable:
95
111
  *
96
- * - `<vaadin-time-picker-combo-box>` - an internal version of [`<vaadin-combo-box>`](#/elements/vaadin-combo-box).
97
- * - `<vaadin-time-picker-overlay>` - has the same API as [`<vaadin-overlay>`](#/elements/vaadin-overlay).
98
112
  * - `<vaadin-time-picker-item>` - has the same API as [`<vaadin-item>`](#/elements/vaadin-item).
99
- * - [`<vaadin-input-container>`](#/elements/vaadin-input-container) - an internal element wrapping the input.
100
- *
101
- * Note: the `theme` attribute value set on `<vaadin-time-picker>` is
102
- * propagated to the internal components listed above.
103
113
  *
104
114
  * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
105
115
  *