291 lines
8.4 KiB
TypeScript
291 lines
8.4 KiB
TypeScript
import wrap from "@vue/web-component-wrapper";
|
|
import { customElement } from "lit/decorators";
|
|
import Vue from "vue";
|
|
import DateRangePicker from "vue2-daterange-picker";
|
|
// @ts-ignore
|
|
import dateRangePickerStyles from "vue2-daterange-picker/dist/vue2-daterange-picker.css";
|
|
import { fireEvent } from "../common/dom/fire_event";
|
|
import {
|
|
localizeWeekdays,
|
|
localizeMonths,
|
|
} from "../common/datetime/localize_date";
|
|
|
|
// Set the current date to the left picker instead of the right picker because the right is hidden
|
|
const CustomDateRangePicker = Vue.extend({
|
|
mixins: [DateRangePicker],
|
|
methods: {
|
|
selectMonthDate() {
|
|
const dt: Date = this.end || new Date();
|
|
// @ts-ignore
|
|
this.changeLeftMonth({
|
|
year: dt.getFullYear(),
|
|
month: dt.getMonth() + 1,
|
|
});
|
|
},
|
|
},
|
|
});
|
|
|
|
const Component = Vue.extend({
|
|
props: {
|
|
timePicker: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
twentyfourHours: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
openingDirection: {
|
|
type: String,
|
|
default: "right",
|
|
},
|
|
disabled: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
ranges: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
startDate: {
|
|
type: [String, Date],
|
|
default() {
|
|
return new Date();
|
|
},
|
|
},
|
|
endDate: {
|
|
type: [String, Date],
|
|
default() {
|
|
return new Date();
|
|
},
|
|
},
|
|
firstDay: {
|
|
type: Number,
|
|
default: 1,
|
|
},
|
|
autoApply: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
language: {
|
|
type: String,
|
|
default: "en",
|
|
},
|
|
},
|
|
render(createElement) {
|
|
// @ts-expect-error
|
|
return createElement(CustomDateRangePicker, {
|
|
props: {
|
|
"time-picker": this.timePicker,
|
|
"auto-apply": this.autoApply,
|
|
opens: this.openingDirection,
|
|
"show-dropdowns": false,
|
|
"time-picker24-hour": this.twentyfourHours,
|
|
disabled: this.disabled,
|
|
ranges: this.ranges ? {} : false,
|
|
"locale-data": {
|
|
firstDay: this.firstDay,
|
|
daysOfWeek: localizeWeekdays(this.language, true),
|
|
monthNames: localizeMonths(this.language, false),
|
|
},
|
|
},
|
|
model: {
|
|
value: {
|
|
startDate: this.startDate,
|
|
endDate: this.endDate,
|
|
},
|
|
callback: (value) => {
|
|
fireEvent(this.$el as HTMLElement, "change", value);
|
|
},
|
|
expression: "dateRange",
|
|
},
|
|
scopedSlots: {
|
|
input() {
|
|
return createElement("slot", {
|
|
domProps: { name: "input" },
|
|
});
|
|
},
|
|
header() {
|
|
return createElement("slot", {
|
|
domProps: { name: "header" },
|
|
});
|
|
},
|
|
ranges() {
|
|
return createElement("slot", {
|
|
domProps: { name: "ranges" },
|
|
});
|
|
},
|
|
footer() {
|
|
return createElement("slot", {
|
|
domProps: { name: "footer" },
|
|
});
|
|
},
|
|
},
|
|
});
|
|
},
|
|
});
|
|
|
|
// Assertion corrects HTMLElement type from package
|
|
const WrappedElement = wrap(
|
|
Vue,
|
|
Component
|
|
) as unknown as CustomElementConstructor;
|
|
|
|
@customElement("date-range-picker")
|
|
class DateRangePickerElement extends WrappedElement {
|
|
constructor() {
|
|
super();
|
|
const style = document.createElement("style");
|
|
style.innerHTML = `
|
|
${dateRangePickerStyles}
|
|
.calendars {
|
|
display: flex;
|
|
flex-wrap: nowrap !important;
|
|
}
|
|
.daterangepicker {
|
|
top: auto;
|
|
box-shadow: var(--ha-card-box-shadow, none);
|
|
background-color: var(--card-background-color);
|
|
border-radius: var(--ha-card-border-radius, 12px);
|
|
border-width: var(--ha-card-border-width, 1px);
|
|
border-style: solid;
|
|
border-color: var(
|
|
--ha-card-border-color,
|
|
var(--divider-color, #e0e0e0)
|
|
);
|
|
color: var(--primary-text-color);
|
|
min-width: initial !important;
|
|
max-height: var(--date-range-picker-max-height);
|
|
overflow-y: auto;
|
|
}
|
|
.daterangepicker:before {
|
|
display: none;
|
|
}
|
|
.daterangepicker:after {
|
|
border-bottom: 6px solid var(--card-background-color);
|
|
}
|
|
.daterangepicker .calendar-table {
|
|
background-color: var(--card-background-color);
|
|
border: none;
|
|
}
|
|
.daterangepicker .calendar-table td,
|
|
.daterangepicker .calendar-table th {
|
|
background-color: transparent;
|
|
color: var(--secondary-text-color);
|
|
border-radius: 0;
|
|
outline: none;
|
|
min-width: 32px;
|
|
height: 32px;
|
|
}
|
|
.daterangepicker td.off,
|
|
.daterangepicker td.off.end-date,
|
|
.daterangepicker td.off.in-range,
|
|
.daterangepicker td.off.start-date {
|
|
background-color: var(--secondary-background-color);
|
|
color: var(--disabled-text-color);
|
|
}
|
|
.daterangepicker td.in-range {
|
|
background-color: var(--light-primary-color);
|
|
color: var(--text-light-primary-color, var(--primary-text-color));
|
|
}
|
|
.daterangepicker td.active,
|
|
.daterangepicker td.active:hover {
|
|
background-color: var(--primary-color);
|
|
color: var(--text-primary-color);
|
|
}
|
|
.daterangepicker td.start-date.end-date {
|
|
border-radius: 50%;
|
|
}
|
|
.daterangepicker td.start-date {
|
|
border-radius: 50% 0 0 50%;
|
|
}
|
|
.daterangepicker td.end-date {
|
|
border-radius: 0 50% 50% 0;
|
|
}
|
|
.reportrange-text {
|
|
background: none !important;
|
|
padding: 0 !important;
|
|
border: none !important;
|
|
}
|
|
.daterangepicker .calendar-table .next span,
|
|
.daterangepicker .calendar-table .prev span {
|
|
border: solid var(--primary-text-color);
|
|
border-width: 0 2px 2px 0;
|
|
}
|
|
.daterangepicker .ranges li {
|
|
outline: none;
|
|
}
|
|
.daterangepicker .ranges li:hover {
|
|
background-color: var(--secondary-background-color);
|
|
}
|
|
.daterangepicker .ranges li.active {
|
|
background-color: var(--primary-color);
|
|
color: var(--text-primary-color);
|
|
}
|
|
.daterangepicker select.ampmselect,
|
|
.daterangepicker select.hourselect,
|
|
.daterangepicker select.minuteselect,
|
|
.daterangepicker select.secondselect {
|
|
background: transparent;
|
|
border: 1px solid var(--divider-color);
|
|
color: var(--primary-color);
|
|
}
|
|
.daterangepicker .drp-buttons .btn {
|
|
border: 1px solid var(--primary-color);
|
|
background-color: transparent;
|
|
color: var(--primary-color);
|
|
border-radius: 4px;
|
|
padding: 8px;
|
|
cursor: pointer;
|
|
}
|
|
.calendars-container {
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
.drp-calendar.col.right .calendar-table {
|
|
display: none;
|
|
}
|
|
.daterangepicker.show-ranges .drp-calendar.left {
|
|
border-left: 0px;
|
|
}
|
|
.daterangepicker .drp-calendar.left {
|
|
padding: 8px;
|
|
width: unset;
|
|
max-width: unset;
|
|
min-width: 270px;
|
|
}
|
|
.daterangepicker.show-calendar .ranges {
|
|
margin-top: 0;
|
|
padding-top: 8px;
|
|
border-right: 1px solid var(--divider-color);
|
|
}
|
|
@media only screen and (max-width: 800px) {
|
|
.calendars {
|
|
flex-direction: column;
|
|
}
|
|
}
|
|
.calendar-table {
|
|
padding: 0 !important;
|
|
}
|
|
.daterangepicker.ltr {
|
|
direction: ltr;
|
|
text-align: left;
|
|
}
|
|
.vue-daterange-picker{
|
|
min-width: unset !important;
|
|
display: block !important;
|
|
}
|
|
`;
|
|
const shadowRoot = this.shadowRoot!;
|
|
shadowRoot.appendChild(style);
|
|
// Stop click events from reaching the document, otherwise it will close the picker immediately.
|
|
shadowRoot.addEventListener("click", (ev) => ev.stopPropagation());
|
|
}
|
|
}
|
|
|
|
declare global {
|
|
interface HTMLElementTagNameMap {
|
|
"date-range-picker": DateRangePickerElement;
|
|
}
|
|
}
|