Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7b98e31a4 | ||
|
|
a92bb7915c | ||
|
|
6258b55518 | ||
|
|
b4663377a4 | ||
|
|
1dc6152986 | ||
|
|
8e11f71b48 | ||
|
|
c646fc9c9e | ||
|
|
2791d8109c | ||
|
|
14cc1a2c10 | ||
|
|
76a52f0c9f | ||
|
|
ce22ceb808 | ||
|
|
45d3364959 | ||
|
|
6ac3d62823 |
@@ -9,17 +9,27 @@
|
||||
|
||||
## Overview
|
||||
|
||||
This is a Time Picker card for [Home Assistant](https://www.home-assistant.io/)'s [Lovelace UI](https://www.home-assistant.io/lovelace).
|
||||
This is a Time Picker Card for [Home Assistant](https://www.home-assistant.io/)'s [Lovelace UI](https://www.home-assistant.io/lovelace).
|
||||
|
||||
Requires an [Input Datetime](https://www.home-assistant.io/integrations/input_datetime/) that has time (`has_time: true`).
|
||||
|
||||
## Screenshots
|
||||
|
||||
### Default config - card name shown, 24 hour mode
|
||||
|
||||

|
||||
|
||||
### Custom config - hidden card name, 12 hour mode
|
||||
|
||||

|
||||
|
||||

|
||||
### Custom config - hidden card name, 12 hour mode with a "single" hour mode picker
|
||||
|
||||

|
||||
|
||||
### Using a custom theme
|
||||
|
||||

|
||||
|
||||
## Installation
|
||||
|
||||
@@ -33,6 +43,15 @@ resources:
|
||||
|
||||
## Usage
|
||||
|
||||
### Visual Editor
|
||||
|
||||
Time Picker Card supports Lovelace's Visual Editor. Click the + button to add a card and search for time picker.
|
||||
|
||||

|
||||
|
||||
|
||||
### YAML
|
||||
|
||||
```yaml
|
||||
type: 'custom:time-picker-card'
|
||||
entity: input_datetime.alarm_time
|
||||
@@ -54,8 +73,15 @@ hide:
|
||||
| hour_mode | `12` or `24` | **Optional** | Hour format. If `12`, card will show AM/PM picker | `24` |
|
||||
| hour_step | number | **Optional** | Hour change when clicking arrows | `1` |
|
||||
| minute_step | number | **Optional** | Minute change when clicking arrows | `5` |
|
||||
| layout | object | **Optional** | Card Layout configuration | `none` |
|
||||
| hide | object | **Optional** | Hide object | `none` |
|
||||
|
||||
## Layout Object
|
||||
|
||||
| Name | Type | Requirement | Description | Default |
|
||||
| --------- | -------------------- | ------------ | -------------------------------------------------------------------------------------------------- | -------- |
|
||||
| hour_mode | `single` or `double` | **Optional** | Whether to show both AM/PM or just the current mode. In `single` mode, tap the value to change it. | `double` |
|
||||
|
||||
## Hide Object
|
||||
|
||||
| Name | Type | Requirement | Description | Default |
|
||||
@@ -64,12 +90,16 @@ hide:
|
||||
|
||||
## Theme Variables
|
||||
|
||||
| Name | Default | Description |
|
||||
| ------------------------------- | --------------------------- | ------------------------------------------- |
|
||||
| --tpc-elements-background-color | `var(--dark-primary-color)` | Background color for header and ui elements |
|
||||
| --tpc-icon-color | `var(--primary-text-color)` | Arrow color |
|
||||
| --tpc-text-color | `white` | Text color |
|
||||
| --tpc-accent-color | `var(--accent-color)` | AM / PM active color |
|
||||
Time Picker Card will automatically pick up colors from your lovelace theme, but if you want to customize some of them,
|
||||
you can use the following variables in your theme's config file:
|
||||
|
||||
| Name | Default | Description |
|
||||
| ------------------------------------- | ---------------------------- | -------------------------------------- |
|
||||
| time-picker-elements-background-color | `var(--primary-color)` | Background color for header and inputs |
|
||||
| time-picker-icon-color | `var(--primary-text-color)` | Arrow color |
|
||||
| time-picker-text-color | `white` | Text color |
|
||||
| time-picker-accent-color | `var(--primary-color)` | AM / PM active color |
|
||||
| time-picker-off-color | `var(--disabled-text-color)` | AM / PM inactive color |
|
||||
|
||||
## Meta
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 45 KiB |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "time-picker-card",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.5",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "time-picker-card",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.5",
|
||||
"author": "Georgi Gardev <georgi@gardev.com>",
|
||||
"description": "Lovelace time-picker-card",
|
||||
"keywords": [
|
||||
|
||||
@@ -8,13 +8,18 @@ import {
|
||||
TemplateResult,
|
||||
} from 'lit-element';
|
||||
import { ClassInfo, classMap } from 'lit-html/directives/class-map';
|
||||
import { Period } from '../types';
|
||||
import { Period, HourModeLayout } from '../types';
|
||||
|
||||
/**
|
||||
* Renders a Time Period selector with an input for a value and two arrows for step-chaning
|
||||
* the value up and down.
|
||||
*/
|
||||
@customElement('time-period')
|
||||
export class TimePeriodComponent extends LitElement {
|
||||
static readonly EVENT_TOGGLE = 'toggle';
|
||||
|
||||
@property() private period!: Period;
|
||||
@property() private mode!: HourModeLayout;
|
||||
|
||||
private get amClass(): ClassInfo {
|
||||
return { 'time-period': true, active: this.period === Period.AM };
|
||||
@@ -26,12 +31,7 @@ export class TimePeriodComponent extends LitElement {
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<div class="time-period-selector">
|
||||
<div class=${classMap(this.amClass)} @click=${this.onTimePeriodChange}>
|
||||
AM<mwc-ripple></mwc-ripple>
|
||||
</div>
|
||||
<div class=${classMap(this.pmClass)} @click=${this.onTimePeriodChange}>
|
||||
PM<mwc-ripple></mwc-ripple>
|
||||
</div>
|
||||
${this.mode === 'single' ? this.renderSingle() : this.renderDouble()}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,21 @@ export class TimePeriodComponent extends LitElement {
|
||||
this.dispatchEvent(event);
|
||||
}
|
||||
|
||||
private renderSingle(): TemplateResult {
|
||||
return html`<div class="time-period active" @click=${this.onTimePeriodChange}>
|
||||
${this.period}<mwc-ripple></mwc-ripple>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
private renderDouble(): TemplateResult {
|
||||
return html`<div class=${classMap(this.amClass)} @click=${this.onTimePeriodChange}>
|
||||
AM<mwc-ripple></mwc-ripple>
|
||||
</div>
|
||||
<div class=${classMap(this.pmClass)} @click=${this.onTimePeriodChange}>
|
||||
PM<mwc-ripple></mwc-ripple>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
.time-period-selector {
|
||||
@@ -49,8 +64,8 @@ export class TimePeriodComponent extends LitElement {
|
||||
.time-period {
|
||||
width: 30px;
|
||||
padding: 8px;
|
||||
background: var(--tpc-elements-background-color);
|
||||
color: var(--tpc-text-color, #fff);
|
||||
background: var(--tpc-off-color);
|
||||
color: var(--tpc-text-color);
|
||||
text-align: center;
|
||||
font-size: 1em;
|
||||
cursor: pointer;
|
||||
|
||||
@@ -10,6 +10,9 @@ import {
|
||||
import { TimeUnit } from '../models/time-unit';
|
||||
import { Direction } from '../types';
|
||||
|
||||
/**
|
||||
* Renders an AM/PM picker.
|
||||
*/
|
||||
@customElement('time-unit')
|
||||
export class TimeUnitComponent extends LitElement {
|
||||
static readonly EVENT_UPDATE = 'update';
|
||||
|
||||
@@ -2,3 +2,10 @@ import * as pkg from '../package.json';
|
||||
|
||||
export const CARD_VERSION = pkg.version;
|
||||
export const CARD_SIZE = 3;
|
||||
|
||||
export const ENTITY_DOMAIN = 'input_datetime';
|
||||
|
||||
// Config defaults
|
||||
export const DEFAULT_HOUR_STEP = 1;
|
||||
export const DEFAULT_MINUTE_STEP = 5;
|
||||
export const DEFAULT_LAYOUT_HOUR_MODE = 'double';
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
import { computeDomain, HomeAssistant, LovelaceCardConfig } from 'custom-card-helpers';
|
||||
import { HassEntity } from 'home-assistant-js-websocket';
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from 'lit-element';
|
||||
import { DEFAULT_HOUR_STEP, DEFAULT_MINUTE_STEP, ENTITY_DOMAIN } from './const';
|
||||
import { HourMode, HourModeLayout, TimePickerCardConfig } from './types';
|
||||
|
||||
// TODO: Remove this once there's a new release of custom-card-helpers that exports it.
|
||||
export interface LovelaceCardEditor extends HTMLElement {
|
||||
hass?: HomeAssistant;
|
||||
lovelace?: unknown;
|
||||
setConfig(config: LovelaceCardConfig): void;
|
||||
}
|
||||
|
||||
@customElement('time-picker-card-editor')
|
||||
export class TimePickerCardEditor extends LitElement implements LovelaceCardEditor {
|
||||
private static readonly NUMBER_PROPERTIES = ['hour_step', 'minute_step', 'hour_mode'];
|
||||
private static readonly CONFIG_CHANGED_EVENT = 'config-changed';
|
||||
|
||||
@property({ type: Object }) hass!: HomeAssistant;
|
||||
@property() private config!: TimePickerCardConfig;
|
||||
|
||||
private get entity(): HassEntity | undefined {
|
||||
return this.hass.states[this.config.entity];
|
||||
}
|
||||
|
||||
private get datetimeEntities(): Array<string> {
|
||||
// Find all input_datetime entities
|
||||
const datetimeEntities = Object.keys(this.hass.states)
|
||||
.filter((entityId) => computeDomain(entityId) === ENTITY_DOMAIN)
|
||||
.map((entityId) => this.hass.states[entityId]);
|
||||
|
||||
// Return only the datetime entities that have time.
|
||||
return datetimeEntities
|
||||
.filter((entity) => entity.attributes.has_time === true)
|
||||
.map((entity) => entity.entity_id);
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<div class="card-config">
|
||||
<paper-dropdown-menu
|
||||
style="width: 100%"
|
||||
label="Entity (Required)"
|
||||
.configValue=${'entity'}
|
||||
@value-changed=${this.onValueChange}
|
||||
>
|
||||
<paper-listbox
|
||||
slot="dropdown-content"
|
||||
.selected=${this.datetimeEntities.indexOf(this.config.entity)}
|
||||
>
|
||||
${this.datetimeEntities.map((entity) => html`<paper-item>${entity}</paper-item>`)}
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
<div class="side-by-side">
|
||||
<paper-input
|
||||
label="Name (Optional)"
|
||||
.configValue=${'name'}
|
||||
.value=${this.config.name}
|
||||
.placeholder=${this.entity?.attributes.friendly_name}
|
||||
@value-changed=${this.onValueChange}
|
||||
></paper-input>
|
||||
<ha-switch
|
||||
style="margin-left: 10px"
|
||||
.checked="${!Boolean(this.config.hide?.name)}"
|
||||
.configValue="${'hide_name'}"
|
||||
@change="${this.onHideNameChange}"
|
||||
>
|
||||
Show name?
|
||||
</ha-switch>
|
||||
</div>
|
||||
<div class="side-by-side">
|
||||
<paper-input
|
||||
type="number"
|
||||
label="Hour Step (Optional)"
|
||||
.configValue=${'hour_step'}
|
||||
.value=${this.config.hour_step || DEFAULT_HOUR_STEP}
|
||||
@value-changed=${this.onValueChange}
|
||||
></paper-input>
|
||||
<paper-input
|
||||
type="number"
|
||||
label="Minute Step (Optional)"
|
||||
.configValue=${'minute_step'}
|
||||
.value=${this.config.minute_step || DEFAULT_MINUTE_STEP}
|
||||
@value-changed=${this.onValueChange}
|
||||
></paper-input>
|
||||
</div>
|
||||
<div class="side-by-side">
|
||||
<ha-switch
|
||||
.checked="${this.config.hour_mode === 12}"
|
||||
.configValue="${'hour_mode'}"
|
||||
@change="${this.onHourModeChange}"
|
||||
>
|
||||
12-Hour mode
|
||||
</ha-switch>
|
||||
<ha-switch
|
||||
.checked="${this.config.layout?.hour_mode === 'single'}"
|
||||
.configValue="${'hour_mode_layout'}"
|
||||
@change="${this.onHourModeLayoutChange}"
|
||||
>
|
||||
"Single" hour mode layout (in 12-Hour mode only)
|
||||
</ha-switch>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
setConfig(config): void {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
private onHourModeChange({ target: { checked } }): void {
|
||||
const hourMode: HourMode = checked ? 12 : 24;
|
||||
|
||||
const newConfig = { ...this.config, hour_mode: hourMode };
|
||||
this.dispatch(newConfig);
|
||||
}
|
||||
|
||||
private onHourModeLayoutChange({ target: { checked } }): void {
|
||||
const hourModeLayout: HourModeLayout = checked ? 'single' : 'double';
|
||||
|
||||
const newConfig = { ...this.config, layout: { hour_mode: hourModeLayout } };
|
||||
this.dispatch(newConfig);
|
||||
}
|
||||
|
||||
private onHideNameChange({ target: { checked } }): void {
|
||||
const newConfig = { ...this.config, hide: { name: !checked } };
|
||||
this.dispatch(newConfig);
|
||||
}
|
||||
|
||||
private onValueChange(e: CustomEvent): void {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const property = (e.target as any).configValue;
|
||||
let value = e.detail.value;
|
||||
|
||||
if (TimePickerCardEditor.NUMBER_PROPERTIES.indexOf(property) > -1) {
|
||||
value = parseInt(value);
|
||||
|
||||
if (isNaN(value)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.config[property] === value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newConfig = { ...this.config, [property]: value };
|
||||
|
||||
this.dispatch(newConfig);
|
||||
}
|
||||
|
||||
private dispatch(config: TimePickerCardConfig): void {
|
||||
const event = new CustomEvent(TimePickerCardEditor.CONFIG_CHANGED_EVENT, {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
detail: { config },
|
||||
});
|
||||
|
||||
this.dispatchEvent(event);
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
ha-switch {
|
||||
padding: 16px 0;
|
||||
}
|
||||
.side-by-side {
|
||||
display: flex;
|
||||
}
|
||||
.side-by-side > * {
|
||||
flex: 1;
|
||||
padding-right: 4px;
|
||||
}
|
||||
.suffix {
|
||||
margin: 0 8px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,19 @@
|
||||
import { TimeUnit } from './time-unit';
|
||||
import { DEFAULT_HOUR_STEP } from '../const';
|
||||
import { HourMode } from '../types';
|
||||
import { TimeUnit } from './time-unit';
|
||||
|
||||
/**
|
||||
* Represents the hour value of a datetime.
|
||||
*/
|
||||
export class Hour extends TimeUnit {
|
||||
private static readonly DEFAULT_STEP = 1;
|
||||
private static readonly MAX = 24;
|
||||
private static readonly VALUE_LIMIT = 24;
|
||||
|
||||
constructor(value: number, step = Hour.DEFAULT_STEP, private hourMode: HourMode) {
|
||||
super(value, step, Hour.MAX);
|
||||
constructor(value: number, step = DEFAULT_HOUR_STEP, private hourMode: HourMode) {
|
||||
super(value, step, Hour.VALUE_LIMIT);
|
||||
}
|
||||
|
||||
get maxValue(): number {
|
||||
return this.hourMode || Hour.MAX;
|
||||
return this.hourMode || Hour.VALUE_LIMIT;
|
||||
}
|
||||
|
||||
togglePeriod(): void {
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import { DEFAULT_MINUTE_STEP } from '../const';
|
||||
import { TimeUnit } from './time-unit';
|
||||
|
||||
/**
|
||||
* * Represents the minute value of a datetime.
|
||||
*/
|
||||
export class Minute extends TimeUnit {
|
||||
private static readonly DEFAULT_STEP = 5;
|
||||
private static readonly MAX = 60;
|
||||
private static readonly VALUE_LIMIT = 60;
|
||||
|
||||
maxValue = Minute.MAX;
|
||||
maxValue = Minute.VALUE_LIMIT;
|
||||
|
||||
constructor(value: number, step = Minute.DEFAULT_STEP) {
|
||||
super(value, step, Minute.MAX);
|
||||
constructor(value: number, step = DEFAULT_MINUTE_STEP) {
|
||||
super(value, step, Minute.VALUE_LIMIT);
|
||||
}
|
||||
|
||||
protected isValidString(valueStr: string): boolean {
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { Direction } from '../types';
|
||||
|
||||
/**
|
||||
* Represents a single unit of a datetime oobject - e.g. hours or minutes.
|
||||
*/
|
||||
export abstract class TimeUnit {
|
||||
/**
|
||||
* Return true if the valueStr can be set as a value of this instance.
|
||||
* Whether {@param valueStr} can be set as a value of this instance.
|
||||
*/
|
||||
protected abstract isValidString(valueStr: string): boolean;
|
||||
|
||||
@@ -23,28 +26,36 @@ export abstract class TimeUnit {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a value from {@param stringValue}, if it can be parsed and is valid.
|
||||
* @param stringValue
|
||||
*/
|
||||
setStringValue(stringValue: string): void {
|
||||
if (this.isValidString(stringValue)) {
|
||||
this.setValue(parseInt(stringValue));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the value in {@param direction} by the step size specified in the constructoor.
|
||||
* @param direction
|
||||
*/
|
||||
stepUpdate(direction: Direction): void {
|
||||
direction === Direction.UP ? this.increment() : this.decrement();
|
||||
}
|
||||
|
||||
increment(): void {
|
||||
toString(): string {
|
||||
return this.value < 10 ? `0${this.value}` : this.value.toString();
|
||||
}
|
||||
|
||||
private increment(): void {
|
||||
this.setValue(this.value + this._step);
|
||||
}
|
||||
|
||||
decrement(): void {
|
||||
private decrement(): void {
|
||||
this.setValue(this.value - this._step);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this.value < 10 ? `0${this.value}` : this.value.toString();
|
||||
}
|
||||
|
||||
protected setValue(newValue: number): void {
|
||||
if (newValue >= this._limit || newValue < 0) {
|
||||
newValue = (newValue + this._limit) % this._limit;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { HomeAssistant } from 'custom-card-helpers';
|
||||
import { computeDomain, HomeAssistant, LovelaceCard } from 'custom-card-helpers';
|
||||
import { HassEntity } from 'home-assistant-js-websocket';
|
||||
import {
|
||||
css,
|
||||
@@ -11,7 +11,8 @@ import {
|
||||
} from 'lit-element';
|
||||
import './components/time-period.component';
|
||||
import './components/time-unit.component';
|
||||
import { CARD_SIZE, CARD_VERSION } from './const';
|
||||
import './editor';
|
||||
import { CARD_SIZE, CARD_VERSION, DEFAULT_LAYOUT_HOUR_MODE, ENTITY_DOMAIN } from './const';
|
||||
import { Hour } from './models/hour';
|
||||
import { Minute } from './models/minute';
|
||||
import { Partial } from './partials';
|
||||
@@ -23,9 +24,18 @@ console.info(
|
||||
'color: white; font-weight: bold; background: dimgray'
|
||||
);
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
(window as any).customCards = (window as any).customCards || [];
|
||||
(window as any).customCards.push({
|
||||
type: 'time-picker-card',
|
||||
name: 'Time Picker Card',
|
||||
description: 'A Time Picker card for setting the time value of Input Datetime entities.',
|
||||
});
|
||||
/* eslint-enable @typescript-eslint/no-explicit-any */
|
||||
|
||||
@customElement('time-picker-card')
|
||||
export class TimePickerCard extends LitElement {
|
||||
@property() private hass!: HomeAssistant;
|
||||
export class TimePickerCard extends LitElement implements LovelaceCard {
|
||||
@property({ type: Object }) hass!: HomeAssistant;
|
||||
@property() private config!: TimePickerCardConfig;
|
||||
@property() private hour!: Hour;
|
||||
@property() private minute!: Minute;
|
||||
@@ -52,13 +62,13 @@ export class TimePickerCard extends LitElement {
|
||||
return Partial.error('Entity not found', this.config);
|
||||
}
|
||||
|
||||
if (!this.entity.entity_id.startsWith('input_datetime')) {
|
||||
return Partial.error('You must set an input_datetime entity', this.config);
|
||||
if (computeDomain(this.entity.entity_id) !== ENTITY_DOMAIN) {
|
||||
return Partial.error(`You must set an ${ENTITY_DOMAIN} entity`, this.config);
|
||||
}
|
||||
|
||||
if (!this.entity.attributes.has_time) {
|
||||
return Partial.error(
|
||||
'You must set an input_datetime entity that sets has_time: true',
|
||||
`You must set an ${ENTITY_DOMAIN} entity that sets has_time: true`,
|
||||
this.config
|
||||
);
|
||||
}
|
||||
@@ -79,6 +89,7 @@ export class TimePickerCard extends LitElement {
|
||||
${this.shouldShowPeriod
|
||||
? html`<time-period
|
||||
.period=${this.period}
|
||||
.mode=${this.config.layout?.hour_mode ?? DEFAULT_LAYOUT_HOUR_MODE}
|
||||
@toggle=${this.onPeriodToggle}
|
||||
></time-period>`
|
||||
: ''}
|
||||
@@ -119,7 +130,7 @@ export class TimePickerCard extends LitElement {
|
||||
|
||||
const time = `${this.hour.value}:${this.minute.value}:00`;
|
||||
|
||||
return this.hass.callService('input_datetime', 'set_datetime', {
|
||||
return this.hass.callService(ENTITY_DOMAIN, 'set_datetime', {
|
||||
entity_id: this.entity!.entity_id,
|
||||
time,
|
||||
});
|
||||
@@ -130,12 +141,13 @@ export class TimePickerCard extends LitElement {
|
||||
:host {
|
||||
--tpc-elements-background-color: var(
|
||||
--time-picker-elements-background-color,
|
||||
var(--dark-primary-color)
|
||||
var(--primary-color)
|
||||
);
|
||||
|
||||
--tpc-icon-color: var(--time-picker-icon-color, var(--primary-text-color));
|
||||
--tpc-text-color: var(--time-picker-text-color, #fff);
|
||||
--tpc-accent-color: var(--time-picker-accent-color, var(--accent-color));
|
||||
--tpc-accent-color: var(--time-picker-accent-color, var(--primary-color));
|
||||
--tpc-off-color: var(--time-picker-off-color, var(--disabled-text-color));
|
||||
}
|
||||
|
||||
.time-picker-header {
|
||||
@@ -155,4 +167,22 @@ export class TimePickerCard extends LitElement {
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
static getStubConfig(
|
||||
_: HomeAssistant,
|
||||
entities: Array<string>
|
||||
): Omit<TimePickerCardConfig, 'type'> {
|
||||
const datetimeEntity = entities.find((entityId) => computeDomain(entityId) === ENTITY_DOMAIN);
|
||||
|
||||
return {
|
||||
entity: datetimeEntity || 'input_datetime.example_entity',
|
||||
hour_mode: 24,
|
||||
hour_step: 1,
|
||||
minute_step: 5,
|
||||
};
|
||||
}
|
||||
|
||||
static getConfigElement(): LovelaceCard {
|
||||
return document.createElement('time-picker-card-editor') as LovelaceCard;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,18 @@ export interface TimePickerCardConfig extends LovelaceCardConfig {
|
||||
hour_mode?: HourMode;
|
||||
hour_step?: number;
|
||||
minute_step?: number;
|
||||
layout?: TimePickerLayoutConfig;
|
||||
hide?: TimePickerHideConfig;
|
||||
}
|
||||
|
||||
export type HourMode = 12 | 24 | undefined;
|
||||
|
||||
export interface TimePickerLayoutConfig {
|
||||
hour_mode: HourModeLayout;
|
||||
}
|
||||
|
||||
export type HourModeLayout = 'single' | 'double';
|
||||
|
||||
export interface TimePickerHideConfig {
|
||||
name: boolean;
|
||||
}
|
||||
@@ -19,8 +28,6 @@ export enum Direction {
|
||||
}
|
||||
|
||||
export enum Period {
|
||||
AM = 'am',
|
||||
PM = 'pm',
|
||||
AM = 'AM',
|
||||
PM = 'PM',
|
||||
}
|
||||
|
||||
export type HourMode = 12 | 24 | undefined;
|
||||
|
||||