New date picker (#11555)

This commit is contained in:
Bram Kragten 2022-02-05 01:19:36 +01:00 committed by GitHub
parent 9b97faa5e3
commit 45e6ec1ee2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 245 additions and 146 deletions

View File

@ -89,13 +89,13 @@
"@polymer/polymer": "3.4.1",
"@thomasloven/round-slider": "0.5.4",
"@vaadin/combo-box": "^22.0.4",
"@vaadin/date-picker": "^22.0.4",
"@vaadin/vaadin-themable-mixin": "^22.0.4",
"@vibrant/color": "^3.2.1-alpha.1",
"@vibrant/core": "^3.2.1-alpha.1",
"@vibrant/quantizer-mmcq": "^3.2.1-alpha.1",
"@vue/web-component-wrapper": "^1.2.0",
"@webcomponents/webcomponentsjs": "^2.2.10",
"app-datepicker": "^5.0.1",
"chart.js": "^3.3.2",
"comlink": "^4.3.1",
"core-js": "^3.15.2",

View File

@ -1,135 +1,76 @@
import { mdiCalendar } from "@mdi/js";
import "@polymer/paper-input/paper-input";
import "@vaadin/date-picker/theme/material/vaadin-date-picker-light";
import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit";
import { customElement, property, query } from "lit/decorators";
import { css, CSSResultGroup, html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import { formatDateNumeric } from "../common/datetime/format_date";
import { fireEvent } from "../common/dom/fire_event";
import { HomeAssistant } from "../types";
import "./ha-svg-icon";
const i18n = {
monthNames: [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
],
weekdays: [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
],
weekdaysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
firstDayOfWeek: 0,
week: "Week",
calendar: "Calendar",
clear: "Clear",
today: "Today",
cancel: "Cancel",
formatTitle: (monthName, fullYear) => monthName + " " + fullYear,
formatDate: (d: { day: number; month: number; year: number }) =>
[
("0000" + String(d.year)).slice(-4),
("0" + String(d.month + 1)).slice(-2),
("0" + String(d.day)).slice(-2),
].join("-"),
parseDate: (text: string) => {
const parts = text.split("-");
const today = new Date();
let date;
let month = today.getMonth();
let year = today.getFullYear();
if (parts.length === 3) {
year = parseInt(parts[0]);
if (parts[0].length < 3 && year >= 0) {
year += year < 50 ? 2000 : 1900;
}
month = parseInt(parts[1]) - 1;
date = parseInt(parts[2]);
} else if (parts.length === 2) {
month = parseInt(parts[0]) - 1;
date = parseInt(parts[1]);
} else if (parts.length === 1) {
date = parseInt(parts[0]);
}
const loadDatePickerDialog = () => import("./ha-dialog-date-picker");
if (date !== undefined) {
return { day: date, month, year };
}
return undefined;
},
export interface datePickerDialogParams {
value?: string;
min?: string;
max?: string;
locale?: string;
onChange: (value: string) => void;
}
const showDatePickerDialog = (
element: HTMLElement,
dialogParams: datePickerDialogParams
): void => {
fireEvent(element, "show-dialog", {
dialogTag: "ha-dialog-date-picker",
dialogImport: loadDatePickerDialog,
dialogParams,
});
};
@customElement("ha-date-input")
export class HaDateInput extends LitElement {
@property({ attribute: false }) public locale!: HomeAssistant["locale"];
@property() public value?: string;
@property({ type: Boolean }) public disabled = false;
@property() public label?: string;
@query("vaadin-date-picker-light", true) private _datePicker;
private _inited = false;
updated(changedProps: PropertyValues) {
if (changedProps.has("value")) {
this._datePicker.value = this.value;
this._inited = true;
}
}
render() {
return html`<vaadin-date-picker-light
return html`<paper-input
.label=${this.label}
.disabled=${this.disabled}
@value-changed=${this._valueChanged}
attr-for-value="value"
.i18n=${i18n}
no-label-float
@click=${this._openDialog}
.value=${this.value
? formatDateNumeric(new Date(this.value), this.locale)
: ""}
>
<paper-input
.label=${this.label}
.disabled=${this.disabled}
no-label-float
>
<ha-svg-icon slot="suffix" .path=${mdiCalendar}></ha-svg-icon>
</paper-input>
</vaadin-date-picker-light>`;
<ha-svg-icon slot="suffix" .path=${mdiCalendar}></ha-svg-icon>
</paper-input>`;
}
private _valueChanged(ev: CustomEvent) {
if (
!this.value ||
(this._inited && !this._compareStringDates(ev.detail.value, this.value))
) {
this.value = ev.detail.value;
private _openDialog() {
if (this.disabled) {
return;
}
showDatePickerDialog(this, {
min: "1970-01-01",
value: this.value,
onChange: (value) => this._valueChanged(value),
locale: this.locale.language,
});
}
private _valueChanged(value: string) {
if (this.value !== value) {
this.value = value;
fireEvent(this, "change");
fireEvent(this, "value-changed", { value: ev.detail.value });
fireEvent(this, "value-changed", { value });
}
}
private _compareStringDates(a: string, b: string): boolean {
const aParts = a.split("-");
const bParts = b.split("-");
let i = 0;
for (const aPart of aParts) {
if (Number(aPart) !== Number(bParts[i])) {
return false;
}
i++;
}
return true;
}
static get styles(): CSSResultGroup {
return css`
paper-input {

View File

@ -0,0 +1,106 @@
import "@material/mwc-button/mwc-button";
import "app-datepicker";
import { css, html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../common/dom/fire_event";
import { haStyleDialog } from "../resources/styles";
import { datePickerDialogParams } from "./ha-date-input";
import "./ha-dialog";
@customElement("ha-dialog-date-picker")
export class HaDialogDatePicker extends LitElement {
@property() public value?: string;
@property({ type: Boolean }) public disabled = false;
@property() public label?: string;
@state() private _params?: datePickerDialogParams;
@state() private _value?: string;
public showDialog(params: datePickerDialogParams): void {
this._params = params;
this._value = params.value;
}
public closeDialog() {
this._params = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
render() {
if (!this._params) {
return html``;
}
return html`<ha-dialog open @closed=${this.closeDialog}>
<app-datepicker
.value=${this._value}
.min=${this._params.min}
.max=${this._params.max}
.locale=${this._params.locale}
@datepicker-value-updated=${this._valueChanged}
></app-datepicker>
<mwc-button slot="secondaryAction" @click=${this._setToday}
>today</mwc-button
>
<mwc-button slot="primaryAction" dialogaction="cancel" class="cancel-btn">
cancel
</mwc-button>
<mwc-button slot="primaryAction" @click=${this._setValue}>ok</mwc-button>
</ha-dialog>`;
}
private _valueChanged(ev: CustomEvent) {
this._value = ev.detail.value;
}
private _setToday() {
this._value = new Date().toISOString().split("T")[0];
}
private _setValue() {
this._params?.onChange(this._value!);
this.closeDialog();
}
static styles = [
haStyleDialog,
css`
ha-dialog {
--dialog-content-padding: 0;
--justify-action-buttons: space-between;
}
app-datepicker {
--app-datepicker-accent-color: var(--primary-color);
--app-datepicker-bg-color: transparent;
--app-datepicker-color: var(--primary-text-color);
--app-datepicker-disabled-day-color: var(--disabled-text-color);
--app-datepicker-focused-day-color: var(--text-primary-color);
--app-datepicker-focused-year-bg-color: var(--primary-color);
--app-datepicker-selector-color: var(--secondary-text-color);
--app-datepicker-separator-color: var(--divider-color);
--app-datepicker-weekday-color: var(--secondary-text-color);
}
app-datepicker::part(calendar-day):focus {
outline: none;
}
@media all and (min-width: 450px) {
ha-dialog {
--mdc-dialog-min-width: 300px;
}
}
@media all and (max-width: 450px), all and (max-height: 500px) {
app-datepicker {
width: 100%;
}
}
`,
];
}
declare global {
interface HTMLElementTagNameMap {
"ha-dialog-date-picker": HaDialogDatePicker;
}
}

View File

@ -23,6 +23,7 @@ class MoreInfoInputDatetime extends LitElement {
this.stateObj.attributes.has_date
? html`
<ha-date-input
.locale=${this.hass.locale}
.value=${`${this.stateObj.attributes.year}-${this.stateObj.attributes.month}-${this.stateObj.attributes.day}`}
.disabled=${UNAVAILABLE_STATES.includes(this.stateObj.state)}
@value-changed=${this._dateChanged}

View File

@ -54,6 +54,7 @@ class HuiInputDatetimeEntityRow extends LitElement implements LovelaceRow {
${stateObj.attributes.has_date
? html`
<ha-date-input
.locale=${this.hass.locale}
.disabled=${UNAVAILABLE_STATES.includes(stateObj.state)}
.value=${`${stateObj.attributes.year}-${stateObj.attributes.month}-${stateObj.attributes.day}`}
@value-changed=${this._dateChanged}

124
yarn.lock
View File

@ -3101,7 +3101,7 @@ __metadata:
languageName: node
linkType: hard
"@polymer/iron-a11y-announcer@npm:^3.0.0, @polymer/iron-a11y-announcer@npm:^3.0.0-pre.26":
"@polymer/iron-a11y-announcer@npm:^3.0.0-pre.26":
version: 3.0.2
resolution: "@polymer/iron-a11y-announcer@npm:3.0.2"
dependencies:
@ -3223,7 +3223,7 @@ __metadata:
languageName: node
linkType: hard
"@polymer/iron-media-query@npm:^3.0.0, @polymer/iron-media-query@npm:^3.0.0-pre.26":
"@polymer/iron-media-query@npm:^3.0.0-pre.26":
version: 3.0.1
resolution: "@polymer/iron-media-query@npm:3.0.1"
dependencies:
@ -3527,6 +3527,13 @@ __metadata:
languageName: node
linkType: hard
"@reallyland/esm@npm:^0.0.1":
version: 0.0.1
resolution: "@reallyland/esm@npm:0.0.1"
checksum: 08ba000c1c6970a15f06649b33861e775bfd0aef41b76e4d58430580ddf1fbc35a00637fbd14a8ecdfa06069d96bc29331b60b1aaeb77b233de8463f4aa4c885
languageName: node
linkType: hard
"@rollup/plugin-babel@npm:^5.2.0, @rollup/plugin-babel@npm:^5.2.1":
version: 5.3.0
resolution: "@rollup/plugin-babel@npm:5.3.0"
@ -3979,6 +3986,22 @@ __metadata:
languageName: node
linkType: hard
"@types/lodash-es@npm:^4.17.4":
version: 4.17.5
resolution: "@types/lodash-es@npm:4.17.5"
dependencies:
"@types/lodash": "*"
checksum: 8910f646310aa008bb45071619fe85abf917bbc2c7cc0af883a971de261723247695a58dd966bfa9defd946cef79811d8b075eb6f0af12343080ab0ae6614e12
languageName: node
linkType: hard
"@types/lodash@npm:*":
version: 4.14.178
resolution: "@types/lodash@npm:4.14.178"
checksum: a69a04a60bfc5257c3130a554b4efa0c383f0141b7b3db8ab7cf07ad2a46ea085fce66d0242da41da7e5647b133d5dfb2c15add9cbed8d7fef955e4a1e5b3128
languageName: node
linkType: hard
"@types/marked@npm:^2":
version: 2.0.5
resolution: "@types/marked@npm:2.0.5"
@ -4035,6 +4058,20 @@ __metadata:
languageName: node
linkType: hard
"@types/parse5@npm:^6.0.0":
version: 6.0.3
resolution: "@types/parse5@npm:6.0.3"
checksum: ddb59ee4144af5dfcc508a8dcf32f37879d11e12559561e65788756b95b33e6f03ea027d88e1f5408f9b7bfb656bf630ace31a2169edf44151daaf8dd58df1b7
languageName: node
linkType: hard
"@types/prismjs@npm:^1.16.5":
version: 1.26.0
resolution: "@types/prismjs@npm:1.26.0"
checksum: cd5e7a6214c1f4213ec512a5fcf6d8fe37a56b813fc57ac95b5ff5ee074742bfdbd2f2730d9fd985205bf4586728e09baa97023f739e5aa1c9735a7c1ecbd11a
languageName: node
linkType: hard
"@types/qrcode@npm:^1.4.2":
version: 1.4.2
resolution: "@types/qrcode@npm:1.4.2"
@ -4230,19 +4267,6 @@ __metadata:
languageName: node
linkType: hard
"@vaadin/button@npm:^22.0.4":
version: 22.0.4
resolution: "@vaadin/button@npm:22.0.4"
dependencies:
"@polymer/polymer": ^3.0.0
"@vaadin/component-base": ^22.0.4
"@vaadin/vaadin-lumo-styles": ^22.0.4
"@vaadin/vaadin-material-styles": ^22.0.4
"@vaadin/vaadin-themable-mixin": ^22.0.4
checksum: 70f8eeddd7c8d19eb859f2dd5f848e9b6b83f1f4bc8cb3d1fdc613f0637df9c04f0f91e49d23c4d390ce4ffa8a301ea77c364c29de278e8c32e5e7ccbcaf8f67
languageName: node
linkType: hard
"@vaadin/combo-box@npm:^22.0.4":
version: 22.0.4
resolution: "@vaadin/combo-box@npm:22.0.4"
@ -4275,26 +4299,6 @@ __metadata:
languageName: node
linkType: hard
"@vaadin/date-picker@npm:^22.0.4":
version: 22.0.4
resolution: "@vaadin/date-picker@npm:22.0.4"
dependencies:
"@open-wc/dedupe-mixin": ^1.3.0
"@polymer/iron-a11y-announcer": ^3.0.0
"@polymer/iron-media-query": ^3.0.0
"@polymer/polymer": ^3.2.0
"@vaadin/button": ^22.0.4
"@vaadin/component-base": ^22.0.4
"@vaadin/field-base": ^22.0.4
"@vaadin/input-container": ^22.0.4
"@vaadin/vaadin-lumo-styles": ^22.0.4
"@vaadin/vaadin-material-styles": ^22.0.4
"@vaadin/vaadin-overlay": ^22.0.4
"@vaadin/vaadin-themable-mixin": ^22.0.4
checksum: bfc0bc3a9bec920d7a0b0d2b3968f6c5ca17cea752f37b7d707e8912b8c35e2780b1a78d4cdca1094519cb70554f95ee5ab69f212c677482935a7a4fc3b42a43
languageName: node
linkType: hard
"@vaadin/field-base@npm:^22.0.4":
version: 22.0.4
resolution: "@vaadin/field-base@npm:22.0.4"
@ -5125,6 +5129,18 @@ __metadata:
languageName: node
linkType: hard
"app-datepicker@npm:^5.0.1":
version: 5.0.1
resolution: "app-datepicker@npm:5.0.1"
dependencies:
"@material/mwc-button": ^0.25.3
lit: ^2.0.2
nodemod: 2.8.4
tslib: ^2.3.0
checksum: 619b6e725aca8a89a4ed28bd2390ad8e1c5a8da075928947d270e3dd5df98f6082fdf7ca1190d382d3ad73bacabcd048af21c8579e8f40c0032eba74a2e8c667
languageName: node
linkType: hard
"append-buffer@npm:^1.0.2":
version: 1.0.2
resolution: "append-buffer@npm:1.0.2"
@ -9158,7 +9174,6 @@ fsevents@^1.2.7:
"@typescript-eslint/eslint-plugin": ^4.32.0
"@typescript-eslint/parser": ^4.32.0
"@vaadin/combo-box": ^22.0.4
"@vaadin/date-picker": ^22.0.4
"@vaadin/vaadin-themable-mixin": ^22.0.4
"@vibrant/color": ^3.2.1-alpha.1
"@vibrant/core": ^3.2.1-alpha.1
@ -9167,6 +9182,7 @@ fsevents@^1.2.7:
"@web/dev-server": ^0.0.24
"@web/dev-server-rollup": ^0.2.11
"@webcomponents/webcomponentsjs": ^2.2.10
app-datepicker: ^5.0.1
babel-loader: ^8.2.2
chai: ^4.3.4
chart.js: ^3.3.2
@ -10818,6 +10834,17 @@ fsevents@^1.2.7:
languageName: node
linkType: hard
"lit-ntml@npm:^2.18.2":
version: 2.20.0
resolution: "lit-ntml@npm:2.20.0"
dependencies:
"@reallyland/esm": ^0.0.1
parse5: ^6.0.1
tslib: ^2.0.2
checksum: 49d59ff05959ed725799c69691aa81d759426900150f91edd17debb1cd05ace1ac766172d80b196610e1f1b7b87215cccd9ba13e93638e4f75afeab87303471c
languageName: node
linkType: hard
"lit-vaadin-helpers@npm:^0.3.0":
version: 0.3.0
resolution: "lit-vaadin-helpers@npm:0.3.0"
@ -11961,6 +11988,20 @@ fsevents@^1.2.7:
languageName: node
linkType: hard
"nodemod@npm:2.8.4":
version: 2.8.4
resolution: "nodemod@npm:2.8.4"
dependencies:
"@types/lodash-es": ^4.17.4
"@types/parse5": ^6.0.0
"@types/prismjs": ^1.16.5
lit-ntml: ^2.18.2
normalize-diacritics: ^2.13.2
tslib: ^2.1.0
checksum: 6dbf61aeca7d1c58d8e122a0801179daccdbd23a0ded0b602cc94c1a20bf664d08b817c57b7489af4193b3b044505bb7c849491eea5eea9248fa65e16b217da0
languageName: node
linkType: hard
"nopt@npm:^4.0.1":
version: 4.0.1
resolution: "nopt@npm:4.0.1"
@ -11984,6 +12025,15 @@ fsevents@^1.2.7:
languageName: node
linkType: hard
"normalize-diacritics@npm:^2.13.2":
version: 2.14.0
resolution: "normalize-diacritics@npm:2.14.0"
dependencies:
tslib: ^2.1.0
checksum: f29169bebce5227ac270545fde176db2d52890fb0caa8c394454dbd8553c7f4e3c09a5535e9ee6b139c558ccabbdf1e08bb153ded69cfc58f2f9e472f48703c3
languageName: node
linkType: hard
"normalize-package-data@npm:^2.3.2, normalize-package-data@npm:^2.3.4":
version: 2.5.0
resolution: "normalize-package-data@npm:2.5.0"
@ -15227,7 +15277,7 @@ fsevents@^1.2.7:
languageName: node
linkType: hard
"tslib@npm:^2.0.1, tslib@npm:^2.1.0, tslib@npm:^2.2.0":
"tslib@npm:^2.0.1, tslib@npm:^2.0.2, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.3.0":
version: 2.3.1
resolution: "tslib@npm:2.3.1"
checksum: de17a98d4614481f7fcb5cd53ffc1aaf8654313be0291e1bfaee4b4bb31a20494b7d218ff2e15017883e8ea9626599b3b0e0229c18383ba9dce89da2adf15cb9