Skip to content

Commit

Permalink
experiment: add LitElement version of vaadin-date-picker (#6276)
Browse files Browse the repository at this point in the history
  • Loading branch information
web-padawan authored Aug 1, 2023
1 parent 5e0e6dc commit da96769
Show file tree
Hide file tree
Showing 30 changed files with 247 additions and 18 deletions.
1 change: 1 addition & 0 deletions packages/date-picker/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"src",
"!src/vaadin-lit-date-picker-overlay-content.js",
"!src/vaadin-lit-month-calendar.js",
"!src/vaadin-lit-date-picker.js",
"theme",
"vaadin-*.d.ts",
"vaadin-*.js",
Expand Down
38 changes: 35 additions & 3 deletions packages/date-picker/src/vaadin-date-picker-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,18 @@ export const DatePickerMixin = (subclass) =>
* @protected
*/
_selectedDate: {
type: Date,
type: Object,
sync: true,
},

/**
* @type {Date | undefined}
* @protected
*/
_focusedDate: Date,
_focusedDate: {
type: Object,
sync: true,
},

/**
* Selected date.
Expand All @@ -64,6 +68,7 @@ export const DatePickerMixin = (subclass) =>
type: String,
notify: true,
value: '',
sync: true,
},

/**
Expand All @@ -82,6 +87,7 @@ export const DatePickerMixin = (subclass) =>
reflectToAttribute: true,
notify: true,
observer: '_openedChanged',
sync: true,
},

/**
Expand All @@ -99,6 +105,7 @@ export const DatePickerMixin = (subclass) =>
showWeekNumbers: {
type: Boolean,
value: false,
sync: true,
},

/**
Expand All @@ -108,6 +115,7 @@ export const DatePickerMixin = (subclass) =>
_fullscreen: {
type: Boolean,
value: false,
sync: true,
},

/**
Expand Down Expand Up @@ -206,6 +214,7 @@ export const DatePickerMixin = (subclass) =>
*/
i18n: {
type: Object,
sync: true,
value: () => {
return {
monthNames: [
Expand Down Expand Up @@ -276,6 +285,7 @@ export const DatePickerMixin = (subclass) =>
*/
min: {
type: String,
sync: true,
},

/**
Expand All @@ -289,6 +299,7 @@ export const DatePickerMixin = (subclass) =>
*/
max: {
type: String,
sync: true,
},

/**
Expand All @@ -299,6 +310,7 @@ export const DatePickerMixin = (subclass) =>
_minDate: {
type: Date,
computed: '__computeMinOrMaxDate(min)',
sync: true,
},

/**
Expand All @@ -309,6 +321,7 @@ export const DatePickerMixin = (subclass) =>
_maxDate: {
type: Date,
computed: '__computeMinOrMaxDate(max)',
sync: true,
},

/** @private */
Expand All @@ -327,7 +340,10 @@ export const DatePickerMixin = (subclass) =>
_focusOverlayOnOpen: Boolean,

/** @private */
_overlayContent: Object,
_overlayContent: {
type: Object,
sync: true,
},

/**
* In date-picker, unlike other components extending `InputMixin`,
Expand Down Expand Up @@ -490,6 +506,22 @@ export const DatePickerMixin = (subclass) =>
}
}

/**
* Override LitElement lifecycle callback to dispatch `change` event if needed.
* This is necessary to ensure `change` is fired after `value-changed`.
*
* @protected
* @override
*/
updated(props) {
super.updated(props);

if (props.has('value') && this.__dispatchChange) {
this.dispatchEvent(new CustomEvent('change', { bubbles: true }));
this.__dispatchChange = false;
}
}

/**
* Opens the dropdown.
*/
Expand Down
160 changes: 160 additions & 0 deletions packages/date-picker/src/vaadin-lit-date-picker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/**
* @license
* Copyright (c) 2016 - 2023 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import '@vaadin/input-container/src/vaadin-input-container.js';
import './vaadin-date-picker-overlay.js';
import './vaadin-lit-date-picker-overlay-content.js';
import { html, LitElement } from 'lit';
import { ifDefined } from 'lit/directives/if-defined.js';
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
import { TooltipController } from '@vaadin/component-base/src/tooltip-controller.js';
import { InputControlMixin } from '@vaadin/field-base/src/input-control-mixin.js';
import { InputController } from '@vaadin/field-base/src/input-controller.js';
import { LabelledInputController } from '@vaadin/field-base/src/labelled-input-controller.js';
import { inputFieldShared } from '@vaadin/field-base/src/styles/input-field-shared-styles.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
import { DatePickerMixin } from './vaadin-date-picker-mixin.js';
import { datePickerStyles } from './vaadin-date-picker-styles.js';

/**
* LitElement based version of `<vaadin-date-picker>` web component.
*
* ## Disclaimer
*
* This component is an experiment not intended for publishing to npm.
* 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.
*/
class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(ElementMixin(PolylitMixin(LitElement))))) {
static get is() {
return 'vaadin-date-picker';
}

static get styles() {
return [inputFieldShared, datePickerStyles];
}

static get properties() {
return {
/** @private */
_positionTarget: {
type: Object,
sync: true,
},
};
}

/**
* Used by `InputControlMixin` as a reference to the clear button element.
* @protected
* @return {!HTMLElement}
*/
get clearElement() {
return this.$.clearButton;
}

/** @protected */
render() {
return html`
<div class="vaadin-date-picker-container">
<div part="label">
<slot name="label"></slot>
<span part="required-indicator" aria-hidden="true" @click="${this.focus}"></span>
</div>
<vaadin-input-container
part="input-field"
.readonly="${this.readonly}"
.disabled="${this.disabled}"
.invalid="${this.invalid}"
theme="${ifDefined(this._theme)}"
>
<slot name="prefix" slot="prefix"></slot>
<slot name="input"></slot>
<div id="clearButton" part="clear-button" slot="suffix" aria-hidden="true"></div>
<div part="toggle-button" slot="suffix" aria-hidden="true" @click="${this._toggle}"></div>
</vaadin-input-container>
<div part="helper-text">
<slot name="helper"></slot>
</div>
<div part="error-message">
<slot name="error-message"></slot>
</div>
</div>
<vaadin-date-picker-overlay
id="overlay"
?fullscreen="${this._fullscreen}"
theme="${ifDefined(this._theme)}"
.opened="${this.opened}"
@opened-changed="${this._onOpenedChanged}"
@vaadin-overlay-escape-press="${this._onOverlayEscapePress}"
@vaadin-overlay-open="${this._onOverlayOpened}"
@vaadin-overlay-close="${this._onVaadinOverlayClose}"
@vaadin-overlay-closing="${this._onOverlayClosed}"
restore-focus-on-close
no-vertical-overlap
.restoreFocusNode="${this.inputElement}"
.positionTarget="${this._positionTarget}"
></vaadin-date-picker-overlay>
<slot name="tooltip"></slot>
`;
}

/** @protected */
firstUpdated() {
super.firstUpdated();

this.addController(
new InputController(this, (input) => {
this._setInputElement(input);
this._setFocusElement(input);
this.stateTarget = input;
this.ariaTarget = input;
}),
);
this.addController(new LabelledInputController(this.inputElement, this._labelController));

this._tooltipController = new TooltipController(this);
this.addController(this._tooltipController);
this._tooltipController.setPosition('top');
this._tooltipController.setShouldShow((target) => !target.opened);

this._positionTarget = this.shadowRoot.querySelector('[part="input-field"]');

const toggleButton = this.shadowRoot.querySelector('[part="toggle-button"]');
toggleButton.addEventListener('mousedown', (e) => e.preventDefault());
}

/** @private */
_onOpenedChanged(event) {
this.opened = event.detail.value;
}

/** @private */
_onVaadinOverlayClose(e) {
if (e.detail.sourceEvent && e.detail.sourceEvent.composedPath().includes(this)) {
e.preventDefault();
}
}

/** @private */
_toggle(e) {
e.stopPropagation();
if (this.$.overlay.opened) {
this.close();
} else {
this.open();
}
}
}

customElements.define(DatePicker.is, DatePicker);

export { DatePicker };
2 changes: 2 additions & 0 deletions packages/date-picker/test/basic-lit.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import '../src/vaadin-lit-date-picker.js';
import './basic.common.js';
2 changes: 2 additions & 0 deletions packages/date-picker/test/basic-polymer.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import '../src/vaadin-date-picker.js';
import './basic.common.js';
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { expect } from '@esm-bundle/chai';
import { click, escKeyDown, fixtureSync, keyboardEventFor, nextRender, oneEvent, tap } from '@vaadin/testing-helpers';
import { sendKeys } from '@web/test-runner-commands';
import sinon from 'sinon';
import '../src/vaadin-date-picker.js';
import { parseDate } from '../src/vaadin-date-picker-helper.js';
import { close, open, touchTap, waitForOverlayRender } from './helpers.js';

Expand Down
2 changes: 2 additions & 0 deletions packages/date-picker/test/dropdown-lit.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import '../src/vaadin-lit-date-picker.js';
import './dropdown.common.js';
2 changes: 2 additions & 0 deletions packages/date-picker/test/dropdown-polymer.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import '../src/vaadin-date-picker.js';
import './dropdown.common.js';
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
} from '@vaadin/testing-helpers';
import { sendKeys } from '@web/test-runner-commands';
import sinon from 'sinon';
import '../src/vaadin-date-picker.js';
import { getFocusedCell, monthsEqual, open, waitForOverlayRender } from './helpers.js';

describe('dropdown', () => {
Expand Down
3 changes: 3 additions & 0 deletions packages/date-picker/test/events-lit.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import './not-animated-styles.js';
import '../src/vaadin-lit-date-picker.js';
import './events.common.js';
3 changes: 3 additions & 0 deletions packages/date-picker/test/events-polymer.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import './not-animated-styles.js';
import '../src/vaadin-date-picker.js';
import './events.common.js';
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import { expect } from '@esm-bundle/chai';
import { fixtureSync, nextRender } from '@vaadin/testing-helpers';
import { sendKeys } from '@web/test-runner-commands';
import sinon from 'sinon';
import './not-animated-styles.js';
import '../vaadin-date-picker.js';
import { close, open, waitForOverlayRender, waitForScrollToFinish } from './helpers.js';

describe('events', () => {
Expand Down
3 changes: 3 additions & 0 deletions packages/date-picker/test/fullscreen-lit.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import './not-animated-styles.js';
import '../src/vaadin-lit-date-picker.js';
import './fullscreen.common.js';
3 changes: 3 additions & 0 deletions packages/date-picker/test/fullscreen-polymer.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import './not-animated-styles.js';
import '../src/vaadin-date-picker.js';
import './fullscreen.common.js';
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { expect } from '@esm-bundle/chai';
import { fixtureSync, nextRender, nextUpdate, tap } from '@vaadin/testing-helpers';
import { sendKeys, setViewport } from '@web/test-runner-commands';
import sinon from 'sinon';
import '../src/vaadin-date-picker.js';
import { getFocusedCell, open, touchTap, waitForOverlayRender } from './helpers.js';

describe('fullscreen mode', () => {
Expand Down
3 changes: 3 additions & 0 deletions packages/date-picker/test/keyboard-input-lit.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import './not-animated-styles.js';
import '../src/vaadin-lit-date-picker.js';
import './keyboard-input.common.js';
3 changes: 3 additions & 0 deletions packages/date-picker/test/keyboard-input-polymer.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import './not-animated-styles.js';
import '../src/vaadin-date-picker.js';
import './keyboard-input.common.js';
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import { expect } from '@esm-bundle/chai';
import { aTimeout, enter, fixtureSync, nextRender, tap } from '@vaadin/testing-helpers';
import { sendKeys } from '@web/test-runner-commands';
import sinon from 'sinon';
import './not-animated-styles.js';
import '../vaadin-date-picker.js';
import { getAdjustedYear } from '../src/vaadin-date-picker-helper.js';
import { close, getFocusedCell, idleCallback, open, waitForOverlayRender, waitForScrollToFinish } from './helpers.js';

Expand Down
3 changes: 3 additions & 0 deletions packages/date-picker/test/keyboard-navigation-lit.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import './not-animated-styles.js';
import '../src/vaadin-lit-date-picker.js';
import './keyboard-navigation.common.js';
3 changes: 3 additions & 0 deletions packages/date-picker/test/keyboard-navigation-polymer.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import './not-animated-styles.js';
import '../src/vaadin-date-picker.js';
import './keyboard-navigation.common.js';
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import { expect } from '@esm-bundle/chai';
import { aTimeout, fixtureSync, nextRender } from '@vaadin/testing-helpers';
import { sendKeys } from '@web/test-runner-commands';
import sinon from 'sinon';
import './not-animated-styles.js';
import '../vaadin-date-picker.js';
import {
getDefaultI18n,
getFocusedCell,
Expand Down
3 changes: 3 additions & 0 deletions packages/date-picker/test/theme-propagation-lit.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import './not-animated-styles.js';
import '../src/vaadin-lit-date-picker.js';
import './theme-propagation.common.js';
3 changes: 3 additions & 0 deletions packages/date-picker/test/theme-propagation-polymer.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import './not-animated-styles.js';
import '../src/vaadin-date-picker.js';
import './theme-propagation.common.js';
Loading

0 comments on commit da96769

Please sign in to comment.