diff --git a/package.json b/package.json
index 7b3bf4a01..d8d730097 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/src/components/ha-date-input.ts b/src/components/ha-date-input.ts
index c83f5742c..08c259012 100644
--- a/src/components/ha-date-input.ts
+++ b/src/components/ha-date-input.ts
@@ -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`
-
-
-
- `;
+
+ `;
}
- 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 {
diff --git a/src/components/ha-dialog-date-picker.ts b/src/components/ha-dialog-date-picker.ts
new file mode 100644
index 000000000..2cb229db7
--- /dev/null
+++ b/src/components/ha-dialog-date-picker.ts
@@ -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`
+
+ today
+
+ cancel
+
+ ok
+ `;
+ }
+
+ 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;
+ }
+}
diff --git a/src/dialogs/more-info/controls/more-info-input_datetime.ts b/src/dialogs/more-info/controls/more-info-input_datetime.ts
index af1e9aa6a..4d1be5c70 100644
--- a/src/dialogs/more-info/controls/more-info-input_datetime.ts
+++ b/src/dialogs/more-info/controls/more-info-input_datetime.ts
@@ -23,6 +23,7 @@ class MoreInfoInputDatetime extends LitElement {
this.stateObj.attributes.has_date
? html`