From 953242088f113eabd3828079a9658e604d77151f Mon Sep 17 00:00:00 2001 From: Steven Marks Date: Tue, 29 Aug 2023 21:33:15 +0100 Subject: [PATCH] refactor: update editor to be easier to manage --- src/editor.ts | 614 +++++++++++++++++++ src/{index-editor.ts => index-editor.ts.old} | 2 +- src/index.ts | 4 +- src/lib/calendarMode.html.ts | 2 +- src/lib/common.html.ts | 2 +- src/lib/event.func.ts | 4 +- src/lib/eventMode.html.ts | 2 +- src/types.ts | 121 ---- src/types/config.ts | 118 ++++ src/types/editor.ts | 37 ++ src/types/global.ts | 9 + 11 files changed, 786 insertions(+), 129 deletions(-) create mode 100644 src/editor.ts rename src/{index-editor.ts => index-editor.ts.old} (99%) create mode 100644 src/types/config.ts create mode 100644 src/types/editor.ts create mode 100644 src/types/global.ts diff --git a/src/editor.ts b/src/editor.ts new file mode 100644 index 00000000..29896ade --- /dev/null +++ b/src/editor.ts @@ -0,0 +1,614 @@ +import { fireEvent, HomeAssistant, LovelaceCardEditor } from 'custom-card-helpers'; +import { + css, + CSSResult, + html, + LitElement, + TemplateResult, +} from 'lit'; +import { customElement, property, state } from 'lit/decorators.js'; +import { ScopedRegistryHost } from '@lit-labs/scoped-registry-mixin' + + +import { atomicCardConfig } from './types/config'; +import { + DropdownProperty, + InputProperty, + NumberProperty, + Option, + Property, + SwitchProperty, + UnionProperty, +} from './types/editor'; +import { localize } from './localize/localize'; + +import { formfieldDefinition } from '../elements/formfield'; +import { textfieldDefinition } from '../elements/textfield'; +import { switchDefinition } from '../elements/switch'; +import { selectDefinition } from '../elements/select'; +import { style } from './style-editor'; + +@customElement('atomic-calendar-revive-editor') +export class AtomicCalendarReviveEditor extends ScopedRegistryHost(LitElement) implements LovelaceCardEditor { + @property({ attribute: false }) public hass?: HomeAssistant; + @state() private _config!: atomicCardConfig; + @state() private _toggle?: boolean; + @state() private _helpers?: any; + @state() private options?: { [id: string]: Option }; + private _initialized = false; + + static elementDefinitions = { + ...textfieldDefinition, + ...formfieldDefinition, + ...switchDefinition, + ...selectDefinition, + }; + + public setConfig(config: atomicCardConfig): void { + this._config = config; + + this.loadCardHelpers(); + } + + protected shouldUpdate(): boolean { + if (!this._initialized) { + this._initialize(); + } + + return true; + } + + protected render(): TemplateResult { + if (!this.hass || !this._helpers || !this.options) { + return html``; + } + + this._helpers.importMoreInfoControl('climate'); + + return html` +
+ ${Object.entries(this.options).map(option => this.renderOption(option[0], option[1]))} +
+ `; + } + + private renderOption(key: string, option: Option): TemplateResult { + return html` +
+
+ +
${option.name}
+
+
${option.description}
+
+ + ${option.show + ? html` +
+ ${option.properties.map(property => this.renderProperty(property))} +
+ ` + : ''} + `; + } + + private renderProperty(property: UnionProperty): TemplateResult { + if (property.type == 'input') { + return this.renderInputProperty(property); + } + if (property.type == 'number') { + return this.renderNumberProperty(property); + } + if (property.type == 'dropdown') { + return this.renderDropdownProperty(property); + } + if (property.type == 'switch') { + return this.renderSwitchProperty(property); + } + return html``; + } + + private renderInputProperty(property: InputProperty): TemplateResult { + return html` + + `; + } + + private renderSwitchProperty(property: SwitchProperty): TemplateResult { + const checked = this.getPropertyValue(property); + return html` +
+ + + `; + } + + private renderDropdownProperty(property: DropdownProperty): TemplateResult { + return html` + ev.stopPropagation()} + > + ${property.items.map(item => { + return html` + ${item} + `; + })} + + `; + } + + private getPropertyValue(property: Property): any { + if (this._config == undefined) { + return undefined; + } + const parent = property.section ? this._config[property.section] : this._config; + if (parent == undefined) { + return undefined; + } + return parent[property.name]; + } + + private _initialize(): void { + if (this.hass === undefined) { + return; + } + if (this._config === undefined) { + return; + } + if (this._helpers === undefined) { + return; + } + this._initialized = true; + + const linkTargets: string[] = ['_blank', '_self', '_parent', '_top']; + const defaultModes: string[] = ['Event', 'Calendar']; + + this.options = { + main: { + icon: 'eye-settings', + name: localize('main.name'), + description: localize('main.secondary'), + show: false, + properties: [ + { + type: 'input', + name: 'name', + label: localize('main.fields.name'), + }, + { + type: 'number', + name: 'titleLength', + label: localize('main.fields.titleLength'), + min: 0, + max: 99999999999, + }, + { + type: 'number', + name: 'descLength', + label: localize('main.fields.descLength'), + min: 0, + max: 99999999999, + }, + { + type: 'number', + name: 'firstDayOfWeek', + label: localize('main.fields.firstDayOfWeek'), + min: 0, + max: 6 + }, + { + type: 'number', + name: 'maxDaysToShow', + label: localize('main.fields.maxDaysToShow'), + min: 0, + max: 99999999999, + }, + { + type: 'number', + name: 'refreshInterval', + label: localize('main.fields.refreshInterval'), + min: 60, + max: 99999999999, + }, + { + type: 'input', + name: 'dateFormat', + label: localize('main.fields.dateFormat') + }, + { + type: 'input', + name: 'hoursFormat', + label: localize('main.fields.hoursFormat'), + }, + { + type: 'input', + name: 'eventTitle', + label: localize('main.fields.eventTitle'), + }, + { + type: 'dropdown', + items: defaultModes, + name: 'defaultMode', + section: 'main', + label: localize('main.fields.defaultMode'), + selected: defaultModes.indexOf(this._config.defaultMode), + }, + { + type: 'dropdown', + items: linkTargets, + name: 'linkTarget', + section: 'main', + label: localize('main.fields.linkTarget'), + selected: defaultModes.indexOf(this._config.linkTarget), + }, + { + type: 'input', + name: 'cardHeight', + label: localize('main.fields.cardHeight'), + }, + { + type: 'switch', + name: 'showLoader', + label: localize('main.fields.showLoader'), + default: this._config.showLoader, + }, + { + type: 'switch', + name: 'showDate', + label: localize('main.fields.showDate'), + default: this._config.showDate, + }, + { + type: 'switch', + name: 'showDeclined', + label: localize('main.fields.showDeclined'), + default: this._config.showDeclined, + }, + { + type: 'switch', + name: 'sortByStartTime', + label: localize('main.fields.sortByStartTime'), + default: this._config.sortByStartTime, + }, + { + type: 'switch', + name: 'hideFinishedEvents', + label: localize('main.fields.hideFinishedEvents'), + default: this._config.hideFinishedEvents, + }, + { + type: 'switch', + name: 'showLocation', + label: localize('main.fields.showLocation'), + default: this._config.showLocation, + }, + { + type: 'switch', + name: 'showRelativeTime', + label: localize('main.fields.showRelativeTime'), + default: this._config.showRelativeTime, + }, + { + type: 'switch', + name: 'hideDuplicates', + label: localize('main.fields.hideDuplicates'), + default: this._config.hideDuplicates, + }, + { + type: 'switch', + name: 'showMultiDay', + label: localize('main.fields.showMultiDay'), + default: this._config.showMultiDay, + }, + { + type: 'switch', + name: 'showMultiDayEventParts', + label: localize('main.fields.showMultiDayEventParts'), + default: this._config.showMultiDayEventParts, + }, + { + type: 'switch', + name: 'compactMode', + label: localize('main.fields.compactMode'), + default: this._config.compactMode, + }, + { + type: 'switch', + name: 'hoursOnSameLine', + label: localize('main.fields.hoursOnSameLine'), + default: this._config.hoursOnSameLine, + }, + { + type: 'switch', + name: 'showAllDayEvents', + label: localize('main.fields.showAllDayEvents'), + default: this._config.showAllDayEvents, + }, + { + type: 'switch', + name: 'offsetHeaderDate', + label: localize('main.fields.offsetHeaderDate'), + default: this._config.offsetHeaderDate, + }, + ], + }, + event: { + icon: 'calendar-check', + name: localize('event.name'), + description: localize('event.secondary'), + show: false, + properties: [ + { + type: 'input', + name: 'untilText', + label: localize('event.fields.untilText'), + }, + { + type: 'input', + name: 'noEventsForNextDaysText', + label: localize('event.fields.noEventsForNextDaysText'), + }, + { + type: 'input', + name: 'noEventText', + label: localize('event.fields.noEventText'), + }, + { + type: 'input', + name: 'hiddenEventText', + label: localize('event.fields.hiddenEventText'), + }, + { + type: 'switch', + name: 'showCurrentEventLine', + label: localize('event.fields.showCurrentEventLine'), + default: this._config.showCurrentEventLine, + }, + { + type: 'switch', + name: 'showProgressBar', + label: localize('event.fields.showProgressBar'), + default: this._config.showProgressBar, + }, + { + type: 'switch', + name: 'showMonth', + label: localize('event.fields.showMonth'), + default: this._config.showMonth, + }, + { + type: 'switch', + name: 'showWeekDay', + label: localize('event.fields.showWeekDay'), + default: this._config.showWeekDay, + }, + { + type: 'switch', + name: 'showDescription', + label: localize('event.fields.showDescription'), + default: this._config.showDescription, + }, + { + type: 'switch', + name: 'disableEventLink', + label: localize('event.fields.disableEventLink'), + default: this._config.disableEventLink, + }, + { + type: 'switch', + name: 'disableLocationLink', + label: localize('event.fields.disableLocationLink'), + default: this._config.disableLocationLink, + }, + { + type: 'switch', + name: 'showNoEventsForToday', + label: localize('event.fields.showNoEventsForToday'), + default: this._config.showNoEventsForToday, + }, + { + type: 'switch', + name: 'showFullDayProgress', + label: localize('event.fields.showFullDayProgress'), + default: this._config.showFullDayProgress, + }, + { + type: 'switch', + name: 'showEventIcon', + label: localize('event.fields.showEventIcon'), + default: this._config.showEventIcon, + }, + { + type: 'switch', + name: 'showHiddenText', + label: localize('event.fields.showHiddenText'), + default: this._config.showHiddenText, + }, + { + type: 'switch', + name: 'showCalendarName', + label: localize('event.fields.showCalendarName'), + default: this._config.showCalendarName, + }, + { + type: 'switch', + name: 'showWeekNumber', + label: localize('event.fields.showWeekNumber'), + default: this._config.showWeekNumber, + }, + { + type: 'switch', + name: 'showEventDate', + label: localize('event.fields.showEventDate'), + default: this._config.showEventDate, + }, + { + type: 'switch', + name: 'showDatePerEvent', + label: localize('event.fields.showDatePerEvent'), + default: this._config.showDatePerEvent, + }, + { + type: 'switch', + name: 'showTimeRemaining', + label: localize('event.fields.showTimeRemaining'), + default: this._config.showTimeRemaining, + }, + { + type: 'switch', + name: 'showAllDayHours', + label: localize('event.fields.showAllDayHours'), + default: this._config.showAllDayHours, + }, + ], + }, + calendar: { + icon: 'calendar-month-outline', + name: localize('calendar.name'), + description: localize('calendar.secondary'), + show: false, + properties: [ + { + type: 'switch', + name: 'calShowDescription', + label: localize('calendar.fields.calShowDescription'), + default: this._config.calShowDescription, + }, + { + type: 'switch', + name: 'showLastCalendarWeek', + label: localize('calendar.fields.showLastCalendarWeek'), + default: this._config.showLastCalendarWeek, + }, + { + type: 'switch', + name: 'disableCalEventLink', + label: localize('calendar.fields.disableCalEventLink'), + default: this._config.disableCalEventLink, + }, + { + type: 'switch', + name: 'disableCalLocationLink', + label: localize('calendar.fields.disableCalLocationLink'), + default: this._config.disableCalLocationLink, + }, + { + type: 'switch', + name: 'disableCalLink', + label: localize('calendar.fields.disableCalLink'), + default: this._config.disableCalLink, + }, + ], + }, + appearance: { + icon: 'palette', + name: localize('appearance.name'), + description: localize('appearance.secondary'), + show: false, + properties: [ + { + type: 'switch', + name: 'dimFinishedEvents', + label: localize('appearance.fields.dimFinishedEvents'), + default: this._config.dimFinishedEvents, + }, + ], + }, + }; + } + + private async loadCardHelpers(): Promise { + this._helpers = await (window as any).loadCardHelpers(); + } + + private _toggleOption(ev): void { + if (this.options == undefined) { + return undefined; + } + + const show = !this.options[ev.target.option].show; + for (const [key] of Object.entries(this.options)) { + this.options[key].show = false; + } + this.options[ev.target.option].show = show; + this._toggle = !this._toggle; + } + + private _valueChanged(ev): void { + if (!this._config || !this.hass) { + return; + } + const { target } = ev; + const section = target.configSection; + const config = { ...this._config }; + const parent = (section ? { ...config[section] } : config) || {}; + + if (target.configValue) { + if ((target.value === undefined && target.checked === undefined) || target.value === '') { + delete parent[target.configValue]; + if (section) { + this._config = { ...config, [section]: parent }; + } else { + this._config = { ...parent }; + } + } else { + const key = target.configValue; + const rawValue = target.checked !== undefined ? target.checked : target.value; + const value = target.number ? parseFloat(rawValue) : rawValue; + + if (section) { + this._config = { + ...config, + [section]: { ...config[section], [key]: value }, + }; + } else { + this._config = { + ...config, + [key]: value, + }; + } + } + } + fireEvent(this, 'config-changed', { config: this._config }); + } + + static get styles(): CSSResult { + return style; + } +} diff --git a/src/index-editor.ts b/src/index-editor.ts.old similarity index 99% rename from src/index-editor.ts rename to src/index-editor.ts.old index ff40b403..f216fe2a 100644 --- a/src/index-editor.ts +++ b/src/index-editor.ts.old @@ -465,7 +465,7 @@ export class AtomicCalendarReviveEditor extends ScopedRegistryHost(LitElement) i
${localize('main.name')}
-
${localize('main.secondary')}
+
${l${localize('main.name')}}
${options.main.show ? html` diff --git a/src/index.ts b/src/index.ts index d976e8f9..9df2a883 100644 --- a/src/index.ts +++ b/src/index.ts @@ -27,7 +27,7 @@ dayjs.extend(week); dayjs.extend(duration) // Import Card Editor -import './index-editor'; +import './editor'; import CalendarDay from './lib/calendar.class'; import EventClass from './lib/event.class'; @@ -47,7 +47,7 @@ import { } from './lib/eventMode.html'; import { getDate, setNoEventDays, showCalendarLink } from './lib/common.html'; -import { atomicCardConfig } from './types'; +import { atomicCardConfig } from './types/config'; import { CARD_VERSION } from './const'; import { localize } from './localize/localize'; diff --git a/src/lib/calendarMode.html.ts b/src/lib/calendarMode.html.ts index a1d5cbfe..666664e5 100644 --- a/src/lib/calendarMode.html.ts +++ b/src/lib/calendarMode.html.ts @@ -3,7 +3,7 @@ import dayjs from 'dayjs'; import isoWeek from 'dayjs/plugin/isoWeek'; import { html } from 'lit'; import { unsafeHTML } from 'lit/directives/unsafe-html.js'; -import { atomicCardConfig } from '../types'; +import { atomicCardConfig } from '../types/config'; import CalendarDay from './calendar.class'; import { isHtml } from './common.html'; import EventClass from './event.class'; diff --git a/src/lib/common.html.ts b/src/lib/common.html.ts index a2c9542e..0d1ff005 100644 --- a/src/lib/common.html.ts +++ b/src/lib/common.html.ts @@ -1,6 +1,6 @@ import dayjs, { Dayjs } from "dayjs"; import { html } from "lit"; -import { atomicCardConfig } from "../types"; +import { atomicCardConfig } from "../types/config"; import EventClass from "./event.class"; export function showCalendarLink(config, selectedMonth) { diff --git a/src/lib/event.func.ts b/src/lib/event.func.ts index d1f3c274..49592597 100644 --- a/src/lib/event.func.ts +++ b/src/lib/event.func.ts @@ -2,8 +2,8 @@ import { computeStateDomain, HomeAssistant } from 'custom-card-helpers'; import dayjs from 'dayjs'; import customParseFormat from 'dayjs/plugin/customParseFormat'; import isBetween from 'dayjs/plugin/isBetween'; -import { AtomicCalendarReviveEditor } from '../index-editor'; -import { atomicCardConfig, EntityConfig } from '../types'; +import { atomicCardConfig } from '../types/config'; +import { EntityConfig } from '../types'; import CalendarDay from './calendar.class'; import EventClass from './event.class'; diff --git a/src/lib/eventMode.html.ts b/src/lib/eventMode.html.ts index 4ac971db..4b5aa59f 100644 --- a/src/lib/eventMode.html.ts +++ b/src/lib/eventMode.html.ts @@ -1,7 +1,7 @@ import EventClass from "./event.class"; import { html } from 'lit'; import { unsafeHTML } from 'lit/directives/unsafe-html.js'; -import { atomicCardConfig } from "../types"; +import { atomicCardConfig } from "../types/config"; import dayjs from "dayjs"; import { getCurrDayAndMonth, getMultiDayEventParts, isHtml } from "./common.html"; import { localize } from '../localize/localize'; diff --git a/src/types.ts b/src/types.ts index 352d5a9f..abec8bf2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,127 +1,6 @@ import { LovelaceCard, LovelaceCardConfig, LovelaceCardEditor } from 'custom-card-helpers'; -declare global { - interface HTMLElementTagNameMap { - 'atomic-calendar-card-editor': LovelaceCardEditor; - 'atomic-calendar-card': LovelaceCard; - } -} -export interface atomicCardConfig extends LovelaceCardConfig { - entities?: any; - type: string; - name?: string; - entity?: string; - language?: string; - daysToSort?: number; - eventTitle?: string; - - // text translations - fullDayEventText?: string; - untilText?: string; - - maxDaysToShow?: number; - maxEventCount?: number; - showLoader?: boolean; - showLocation?: boolean; - showMonth?: boolean; - showWeekDay?: boolean; - fullTextTime?: boolean; - showCurrentEventLine?: boolean; - showDate?: boolean; - dateFormat?: string; - hoursFormat?: string; - startDaysAhead?: number; - showLastCalendarWeek?: boolean; - showCalNameInEvent?: boolean; - sortByStartTime?: boolean; - disableEventLink?: boolean; - disableLocationLink?: boolean; - linkTarget?: string; - showDeclined?: boolean; - softLimit?: number; - showPrivate?: boolean; - showHiddenText?: boolean; - hiddenEventText?: string; - refreshInterval: number; - showDescription: boolean; - showEventIcon: boolean; - showEventDate: boolean; - showDatePerEvent: boolean; - // color and font settings - nameColor?: string; - dateColor?: string; - dateSize?: number; - descColor?: string; - descSize?: number; - titleLength?: number; - descLength?: number; - showNoEventsForToday?: boolean; - showNoEventDays?: boolean; - noEventText?: string; - noEventsForNextDaysText?: string; - timeColor?: string; - timeSize?: number; - showHours?: boolean; - eventTitleColor?: string; - eventTitleSize?: number; - locationIconColor?: string; - locationLinkColor?: string; - locationTextSize?: number; - - // finished events settings - hideFinishedEvents?: boolean; - dimFinishedEvents?: boolean; - finishedEventOpacity?: number; - finishedEventFilter?: string; - - // days separating - dayWrapperLineColor?: string; - eventBarColor?: string; - eventCalNameColor?: string; - eventCalNameSize?: number; - showProgressBar?: boolean; - showFullDayProgress?: boolean; - progressBarColor?: string; - enableModeChange?: boolean; - defaultMode?: string; - - // Calendar Mode Default Settings - calGridColor?: string; - calDayColor?: string; - calWeekDayColor?: string; - calDateColor?: string; - defaultCalColor?: string; - calEventBackgroundColor?: string; - calEventBackgroundFilter?: string; - calActiveEventBackgroundColor?: string; - calActiveEventBackgroundFilter?: string; - calEventSatColor?: string; - calEventSunColor?: string; - calEventHolidayColor?: string; - calEventHolidayFilter?: string; - calEventIcon1?: string; - calEventIcon1Color?: string; - calEventIcon1Filter?: string; - calEventIcon2?: string; - calEventIcon2Color?: string; - calEventIcon2Filter?: string; - calEventIcon3?: string; - calEventIcon3Color?: string; - calEventIcon3Filter?: string; - calEventTime?: boolean; - firstDayOfWeek?: number; - blacklist?: string; - whitelist?: string; - locationFilter?: string; - disableCalLink?: boolean; - removeDuplicates?: boolean; - - compactMode?: boolean; - hoursOnSameLine?: boolean; - showTimeRemaining?: boolean; - showAllDayHours?: boolean; -} export interface LongDateFormatSpec { LTS: string; diff --git a/src/types/config.ts b/src/types/config.ts new file mode 100644 index 00000000..b3689322 --- /dev/null +++ b/src/types/config.ts @@ -0,0 +1,118 @@ +import { LovelaceCardConfig } from 'custom-card-helpers'; + +export interface atomicCardConfig extends LovelaceCardConfig { + entities?: any; + type: string; + name?: string; + entity?: string; + language?: string; + daysToSort?: number; + eventTitle?: string; + + // text translations + fullDayEventText?: string; + untilText?: string; + + maxDaysToShow?: number; + maxEventCount?: number; + showLoader?: boolean; + showLocation?: boolean; + showMonth?: boolean; + showWeekDay?: boolean; + fullTextTime?: boolean; + showCurrentEventLine?: boolean; + showDate?: boolean; + dateFormat?: string; + hoursFormat?: string; + startDaysAhead?: number; + showLastCalendarWeek?: boolean; + showCalNameInEvent?: boolean; + sortByStartTime?: boolean; + disableEventLink?: boolean; + disableLocationLink?: boolean; + linkTarget: string; + showDeclined?: boolean; + softLimit?: number; + showPrivate?: boolean; + showHiddenText?: boolean; + hiddenEventText?: string; + refreshInterval: number; + showDescription: boolean; + showEventIcon: boolean; + showEventDate: boolean; + showDatePerEvent: boolean; + + // color and font settings + nameColor?: string; + dateColor?: string; + dateSize?: number; + descColor?: string; + descSize?: number; + titleLength?: number; + descLength?: number; + showNoEventsForToday?: boolean; + showNoEventDays?: boolean; + noEventText?: string; + noEventsForNextDaysText?: string; + timeColor?: string; + timeSize?: number; + showHours?: boolean; + eventTitleColor?: string; + eventTitleSize?: number; + locationIconColor?: string; + locationLinkColor?: string; + locationTextSize?: number; + + // finished events settings + hideFinishedEvents?: boolean; + dimFinishedEvents?: boolean; + finishedEventOpacity?: number; + finishedEventFilter?: string; + + // days separating + dayWrapperLineColor?: string; + eventBarColor?: string; + eventCalNameColor?: string; + eventCalNameSize?: number; + showProgressBar?: boolean; + showFullDayProgress?: boolean; + progressBarColor?: string; + enableModeChange?: boolean; + defaultMode: string; + + // Calendar Mode Default Settings + calGridColor?: string; + calDayColor?: string; + calWeekDayColor?: string; + calDateColor?: string; + defaultCalColor?: string; + calEventBackgroundColor?: string; + calEventBackgroundFilter?: string; + calActiveEventBackgroundColor?: string; + calActiveEventBackgroundFilter?: string; + calEventSatColor?: string; + calEventSunColor?: string; + calEventHolidayColor?: string; + calEventHolidayFilter?: string; + calEventIcon1?: string; + calEventIcon1Color?: string; + calEventIcon1Filter?: string; + calEventIcon2?: string; + calEventIcon2Color?: string; + calEventIcon2Filter?: string; + calEventIcon3?: string; + calEventIcon3Color?: string; + calEventIcon3Filter?: string; + calEventTime?: boolean; + firstDayOfWeek?: number; + blacklist?: string; + whitelist?: string; + locationFilter?: string; + disableCalLink?: boolean; + removeDuplicates?: boolean; + + compactMode?: boolean; + hoursOnSameLine?: boolean; + showTimeRemaining?: boolean; + showAllDayHours?: boolean; +} diff --git a/src/types/editor.ts b/src/types/editor.ts new file mode 100644 index 00000000..e54767c0 --- /dev/null +++ b/src/types/editor.ts @@ -0,0 +1,37 @@ +export interface Option { + name: string; + icon: string; + description: string; + show: boolean; + properties: UnionProperty[]; +} + +export interface Property { + type: string; + section?: string; + name: string; + label: string; + default?: string | boolean | number; +} + +export interface DropdownProperty extends Property { + type: 'dropdown'; + items: string[]; + selected: number; +} + +export interface InputProperty extends Property { + type: 'input'; +} + +export interface NumberProperty extends Property { + type: 'number'; + min: number; + max: number; +} + +export interface SwitchProperty extends Property { + type: 'switch'; +} + +export type UnionProperty = DropdownProperty | InputProperty | NumberProperty | SwitchProperty; diff --git a/src/types/global.ts b/src/types/global.ts new file mode 100644 index 00000000..cf53402d --- /dev/null +++ b/src/types/global.ts @@ -0,0 +1,9 @@ +import { LovelaceCard, LovelaceCardEditor } from 'custom-card-helpers'; + + +declare global { + interface HTMLElementTagNameMap { + 'atomic-calendar-card-editor': LovelaceCardEditor; + 'atomic-calendar-card': LovelaceCard; + } +}