Skip to content

Commit

Permalink
experiment: add LitElement based version of vaadin-time-picker (#8080)
Browse files Browse the repository at this point in the history
  • Loading branch information
web-padawan authored Nov 1, 2024
1 parent 9f323a8 commit 869d32d
Show file tree
Hide file tree
Showing 31 changed files with 561 additions and 38 deletions.
113 changes: 113 additions & 0 deletions packages/time-picker/src/vaadin-lit-time-picker-combo-box.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/**
* @license
* Copyright (c) 2018 - 2024 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import './vaadin-lit-time-picker-item.js';
import './vaadin-lit-time-picker-overlay.js';
import './vaadin-lit-time-picker-scroller.js';
import { css, html, LitElement } from 'lit';
import { ifDefined } from 'lit/directives/if-defined.js';
import { ComboBoxMixin } from '@vaadin/combo-box/src/vaadin-combo-box-mixin.js';
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';

/**
* An element used internally by `<vaadin-time-picker>`. Not intended to be used separately.
*
* @customElement
* @extends HTMLElement
* @mixes ComboBoxMixin
* @mixes ThemableMixin
* @private
*/
class TimePickerComboBox extends ComboBoxMixin(ThemableMixin(PolylitMixin(LitElement))) {
static get is() {
return 'vaadin-time-picker-combo-box';
}

static get styles() {
return css`
:host([opened]) {
pointer-events: auto;
}
`;
}

static get properties() {
return {
positionTarget: {
type: Object,
},
};
}

/**
* Tag name prefix used by scroller and items.
* @protected
* @return {string}
*/
get _tagNamePrefix() {
return 'vaadin-time-picker';
}

/**
* Reference to the clear button element.
* @protected
* @return {!HTMLElement}
*/
get clearElement() {
return this.querySelector('[part="clear-button"]');
}

/**
* @override
* @protected
*/
get _inputElementValue() {
return super._inputElementValue;
}

/**
* The setter is overridden to ensure the `_hasInputValue` property
* doesn't wrongly indicate true after the input element's value
* is reverted or cleared programmatically.
*
* @override
* @protected
*/
set _inputElementValue(value) {
super._inputElementValue = value;
this._hasInputValue = value && value.length > 0;
}

/** @protected */
render() {
return html`
<slot></slot>
<vaadin-time-picker-overlay
id="overlay"
.opened="${this._overlayOpened}"
?loading="${this.loading}"
theme="${ifDefined(this._theme)}"
.positionTarget="${this.positionTarget}"
.restoreFocusNode="${this.inputElement}"
no-vertical-overlap
></vaadin-time-picker-overlay>
`;
}
/** @protected */
ready() {
super.ready();

this.allowCustomValue = true;
this._toggleElement = this.querySelector('.toggle-button');

// See https://github.com/vaadin/vaadin-time-picker/issues/145
this.setAttribute('dir', 'ltr');
}
}

defineCustomElement(TimePickerComboBox);
50 changes: 50 additions & 0 deletions packages/time-picker/src/vaadin-lit-time-picker-item.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* @license
* Copyright (c) 2018 - 2024 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import { css, html, LitElement } from 'lit';
import { ComboBoxItemMixin } from '@vaadin/combo-box/src/vaadin-combo-box-item-mixin.js';
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';

/**
* LitElement based version of `<vaadin-time-picker-item>` web component.
*
* ## Disclaimer
*
* This component is an experiment and not yet a part of Vaadin platform.
* There is no ETA regarding specific Vaadin version where it'll land.
* Feel free to try this code in your apps as per Apache 2.0 license.
*/
export class TimePickerItem extends ComboBoxItemMixin(ThemableMixin(DirMixin(PolylitMixin(LitElement)))) {
static get is() {
return 'vaadin-time-picker-item';
}

static get styles() {
return css`
:host {
display: block;
}
:host([hidden]) {
display: none !important;
}
`;
}

/** @protected */
render() {
return html`
<span part="checkmark" aria-hidden="true"></span>
<div part="content">
<slot></slot>
</div>
`;
}
}

defineCustomElement(TimePickerItem);
76 changes: 76 additions & 0 deletions packages/time-picker/src/vaadin-lit-time-picker-overlay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* @license
* Copyright (c) 2018 - 2024 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import { css, html, LitElement } from 'lit';
import { ComboBoxOverlayMixin } from '@vaadin/combo-box/src/vaadin-combo-box-overlay-mixin.js';
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
import { OverlayMixin } from '@vaadin/overlay/src/vaadin-overlay-mixin.js';
import { overlayStyles } from '@vaadin/overlay/src/vaadin-overlay-styles.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';

const timePickerOverlayStyles = css`
#overlay {
width: var(--vaadin-time-picker-overlay-width, var(--_vaadin-time-picker-overlay-default-width, auto));
}
[part='content'] {
display: flex;
flex-direction: column;
height: 100%;
}
`;

/**
* An element used internally by `<vaadin-time-picker>`. Not intended to be used separately.
*
* @extends HTMLElement
* @mixes ComboBoxOverlayMixin
* @mixes DirMixin
* @mixes OverlayMixin
* @mixes ThemableMixin
* @private
*/
export class TimePickerOverlay extends ComboBoxOverlayMixin(
OverlayMixin(DirMixin(ThemableMixin(PolylitMixin(LitElement)))),
) {
static get is() {
return 'vaadin-time-picker-overlay';
}

static get styles() {
return [overlayStyles, timePickerOverlayStyles];
}

static get properties() {
return {
/**
* When true, the overlay is visible and attached to body.
* This property config is overridden to set `sync: true`.
*/
opened: {
type: Boolean,
notify: true,
observer: '_openedChanged',
reflectToAttribute: true,
sync: true,
},
};
}

/** @protected */
render() {
return html`
<div id="backdrop" part="backdrop" hidden></div>
<div part="overlay" id="overlay">
<div part="loader"></div>
<div part="content" id="content"><slot></slot></div>
</div>
`;
}
}

defineCustomElement(TimePickerOverlay);
59 changes: 59 additions & 0 deletions packages/time-picker/src/vaadin-lit-time-picker-scroller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* @license
* Copyright (c) 2015 - 2024 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import { css, html, LitElement } from 'lit';
import { ComboBoxScrollerMixin } from '@vaadin/combo-box/src/vaadin-combo-box-scroller-mixin.js';
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';

/**
* An element used internally by `<vaadin-time-picker>`. Not intended to be used separately.
*
* @extends HTMLElement
* @mixes ComboBoxScrollerMixin
* @private
*/
export class TimePickerScroller extends ComboBoxScrollerMixin(PolylitMixin(LitElement)) {
static get is() {
return 'vaadin-time-picker-scroller';
}

static get styles() {
return css`
:host {
display: block;
min-height: 1px;
overflow: auto;
/* Fixes item background from getting on top of scrollbars on Safari */
transform: translate3d(0, 0, 0);
/* Enable momentum scrolling on iOS */
-webkit-overflow-scrolling: touch;
/* Fixes scrollbar disappearing when 'Show scroll bars: Always' enabled in Safari */
box-shadow: 0 0 0 white;
}
#selector {
border-width: var(--_vaadin-time-picker-items-container-border-width);
border-style: var(--_vaadin-time-picker-items-container-border-style);
border-color: var(--_vaadin-time-picker-items-container-border-color, transparent);
position: relative;
}
`;
}

/** @protected */
render() {
return html`
<div id="selector">
<slot></slot>
</div>
`;
}
}

defineCustomElement(TimePickerScroller);
Loading

0 comments on commit 869d32d

Please sign in to comment.