Skip to content

Commit

Permalink
Add grid section support (#1385)
Browse files Browse the repository at this point in the history
* Add grid support to climate card

* Add grid support to light card

* Add grid support to media_player card

* Add grid support to template card

* Add logic in base card

* Add grid support to vacuum card

* Refactor stateObj

* Add grid support to select card

* Add grid support to template card

* Default set config

* Add grid support to person card

* Add grid support to number card

* Add grid support to media player card

* Add grid support to lock card

* Add grid support to humidifier card

* Add grid support to fan card

* Add grid support to cover card

* Add grid support to alarm control panel card

* Clean stateObj

* Prettier

* Fix missing condition

* Fix missing condition

* Improve get card size

* fix light card action

* Improve get card size
  • Loading branch information
piitaya authored Mar 5, 2024
1 parent 77c6305 commit 5d72e3e
Show file tree
Hide file tree
Showing 28 changed files with 408 additions and 407 deletions.
41 changes: 18 additions & 23 deletions src/cards/alarm-control-panel-card/alarm-control-panel-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ const BUTTONS = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "", "0", "clear"];
*/

@customElement(ALARM_CONTROl_PANEL_CARD_NAME)
export class AlarmControlPanelCard extends MushroomBaseCard implements LovelaceCard {
export class AlarmControlPanelCard
extends MushroomBaseCard<AlarmControlPanelCardConfig>
implements LovelaceCard
{
public static async getConfigElement(): Promise<LovelaceCardEditor> {
await import("./alarm-control-panel-card-editor");
return document.createElement(ALARM_CONTROl_PANEL_CARD_EDITOR_NAME) as LovelaceCardEditor;
Expand All @@ -80,24 +83,21 @@ export class AlarmControlPanelCard extends MushroomBaseCard implements LovelaceC
};
}

@state() private _config?: AlarmControlPanelCardConfig;

@query("#alarmCode") private _input?: HaTextField;
protected get hasControls(): boolean {
return Boolean(this._config?.states?.length);
}

getCardSize(): number | Promise<number> {
return 1;
public getGridSize() {
if (this._config?.show_keypad) {
return [4, 1] as [number, number];
}
return super.getGridSize();
}

@query("#alarmCode") private _input?: HaTextField;

setConfig(config: AlarmControlPanelCardConfig): void {
this._config = {
tap_action: {
action: "more-info",
},
hold_action: {
action: "more-info",
},
...config,
};
super.setConfig(config);
this.loadComponents();
}

Expand All @@ -109,9 +109,7 @@ export class AlarmControlPanelCard extends MushroomBaseCard implements LovelaceC
}

async loadComponents() {
if (!this._config || !this.hass || !this._config.entity) return;
const entityId = this._config.entity;
const stateObj = this.hass.states[entityId] as HassEntity | undefined;
const stateObj = this._stateObj;

if (stateObj && hasCode(stateObj)) {
void import("../../shared/form/mushroom-textfield");
Expand Down Expand Up @@ -144,9 +142,7 @@ export class AlarmControlPanelCard extends MushroomBaseCard implements LovelaceC
}

private get _hasCode(): boolean {
const entityId = this._config?.entity;
if (!entityId) return false;
const stateObj = this.hass.states[entityId] as HassEntity | undefined;
const stateObj = this._stateObj;
if (!stateObj) return false;
return hasCode(stateObj) && Boolean(this._config?.show_keypad);
}
Expand All @@ -156,8 +152,7 @@ export class AlarmControlPanelCard extends MushroomBaseCard implements LovelaceC
return nothing;
}

const entityId = this._config.entity;
const stateObj = this.hass.states[entityId] as HassEntity | undefined;
const stateObj = this._stateObj;

if (!stateObj) {
return this.renderNotFound(this._config);
Expand Down
15 changes: 7 additions & 8 deletions src/cards/chips-card/chips/conditional-chip-editor-legacy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,13 @@ export class ConditionalChipEditor extends LitElement implements LovelaceChipEdi
naturalMenuWidth
>
${CHIP_LIST.map(
(chip) =>
html`
<mwc-list-item .value=${chip}>
${customLocalize(
`editor.chip.chip-picker.types.${chip}`
)}
</mwc-list-item>
`
(chip) => html`
<mwc-list-item .value=${chip}>
${customLocalize(
`editor.chip.chip-picker.types.${chip}`
)}
</mwc-list-item>
`
)}
</mushroom-select>
`}
Expand Down
15 changes: 7 additions & 8 deletions src/cards/chips-card/chips/conditional-chip-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,13 @@ export class ConditionalChipEditor extends LitElement implements LovelaceChipEdi
naturalMenuWidth
>
${CHIP_LIST.map(
(chip) =>
html`
<mwc-list-item .value=${chip}>
${customLocalize(
`editor.chip.chip-picker.types.${chip}`
)}
</mwc-list-item>
`
(chip) => html`
<mwc-list-item .value=${chip}>
${customLocalize(
`editor.chip.chip-picker.types.${chip}`
)}
</mwc-list-item>
`
)}
</mushroom-select>
`}
Expand Down
2 changes: 1 addition & 1 deletion src/cards/chips-card/chips/conditional-chip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const setupConditionChipComponent = async () => {
});
}
const HuiConditionalBase = await loadCustomElement("hui-conditional-base");

// @ts-ignore
class ConditionalChip extends HuiConditionalBase implements LovelaceChip {
public static async getConfigElement(): Promise<LovelaceChipEditor> {
Expand Down
72 changes: 35 additions & 37 deletions src/cards/climate-card/climate-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ registerCustomCard({
});

@customElement(CLIMATE_CARD_NAME)
export class ClimateCard extends MushroomBaseCard implements LovelaceCard {
export class ClimateCard
extends MushroomBaseCard<ClimateCardConfig, ClimateEntity>
implements LovelaceCard
{
public static async getConfigElement(): Promise<LovelaceCardEditor> {
await import("./climate-card-editor");
return document.createElement(CLIMATE_CARD_EDITOR_NAME) as LovelaceCardEditor;
Expand All @@ -66,64 +69,56 @@ export class ClimateCard extends MushroomBaseCard implements LovelaceCard {
};
}

@state() private _config?: ClimateCardConfig;

@state() private _activeControl?: ClimateCardControl;

@state() private _controls: ClimateCardControl[] = [];
private get _controls(): ClimateCardControl[] {
if (!this._config || !this._stateObj) return [];

const stateObj = this._stateObj;
const controls: ClimateCardControl[] = [];
if (isTemperatureControlVisible(stateObj) && this._config.show_temperature_control) {
controls.push("temperature_control");
}
if (isHvacModesVisible(stateObj, this._config.hvac_modes)) {
controls.push("hvac_mode_control");
}
return controls;
}

protected get hasControls(): boolean {
return this._controls.length > 0;
}

_onControlTap(ctrl, e): void {
e.stopPropagation();
this._activeControl = ctrl;
}

getCardSize(): number | Promise<number> {
return 1;
}

setConfig(config: ClimateCardConfig): void {
this._config = {
super.setConfig({
tap_action: {
action: "toggle",
},
hold_action: {
action: "more-info",
},
...config,
};
this.updateControls();
});
this.updateActiveControl();
}

protected updated(changedProperties: PropertyValues) {
super.updated(changedProperties);
if (this.hass && changedProperties.has("hass")) {
this.updateControls();
this.updateActiveControl();
}
}

updateControls() {
if (!this._config || !this.hass || !this._config.entity) return;

const entityId = this._config.entity;
const stateObj = this.hass.states[entityId] as ClimateEntity | undefined;

if (!stateObj) return;

const controls: ClimateCardControl[] = [];
if (!this._config.collapsible_controls || isActive(stateObj)) {
if (isTemperatureControlVisible(stateObj) && this._config.show_temperature_control) {
controls.push("temperature_control");
}
if (isHvacModesVisible(stateObj, this._config.hvac_modes)) {
controls.push("hvac_mode_control");
}
}

this._controls = controls;
updateActiveControl() {
const isActiveControlSupported = this._activeControl
? controls.includes(this._activeControl)
? this._controls.includes(this._activeControl)
: false;
this._activeControl = isActiveControlSupported ? this._activeControl : controls[0];
this._activeControl = isActiveControlSupported ? this._activeControl : this._controls[0];
}

private _handleAction(ev: ActionHandlerEvent) {
Expand All @@ -135,8 +130,7 @@ export class ClimateCard extends MushroomBaseCard implements LovelaceCard {
return nothing;
}

const entityId = this._config.entity;
const stateObj = this.hass.states[entityId] as ClimateEntity | undefined;
const stateObj = this._stateObj;

if (!stateObj) {
return this.renderNotFound(this._config);
Expand Down Expand Up @@ -166,6 +160,9 @@ export class ClimateCard extends MushroomBaseCard implements LovelaceCard {
}
const rtl = computeRTL(this.hass);

const isControlVisible =
(!this._config.collapsible_controls || isActive(stateObj)) && this._controls.length;

return html`
<ha-card class=${classMap({ "fill-container": appearance.fill_container })}>
<mushroom-card .appearance=${appearance} ?rtl=${rtl}>
Expand All @@ -182,10 +179,11 @@ export class ClimateCard extends MushroomBaseCard implements LovelaceCard {
${this.renderBadge(stateObj)}
${this.renderStateInfo(stateObj, appearance, name, stateDisplay)};
</mushroom-state-item>
${this._controls.length > 0
${isControlVisible
? html`
<div class="actions" ?rtl=${rtl}>
${this.renderActiveControl(stateObj)}${this.renderOtherControls()}
${this.renderActiveControl(stateObj)}
${this.renderOtherControls()}
</div>
`
: nothing}
Expand Down
47 changes: 29 additions & 18 deletions src/cards/cover-card/cover-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ registerCustomCard({
});

@customElement(COVER_CARD_NAME)
export class CoverCard extends MushroomBaseCard implements LovelaceCard {
export class CoverCard
extends MushroomBaseCard<CoverCardConfig, CoverEntity>
implements LovelaceCard
{
public static async getConfigElement(): Promise<LovelaceCardEditor> {
await import("./cover-card-editor");
return document.createElement(COVER_CARD_EDITOR_NAME) as LovelaceCardEditor;
Expand All @@ -66,12 +69,12 @@ export class CoverCard extends MushroomBaseCard implements LovelaceCard {
};
}

@state() private _config?: CoverCardConfig;
protected get hasControls(): boolean {
return this._controls.length > 0;
}

@state() private _activeControl?: CoverCardControl;

@state() private _controls: CoverCardControl[] = [];

get _nextControl(): CoverCardControl | undefined {
if (this._activeControl) {
return (
Expand All @@ -91,34 +94,46 @@ export class CoverCard extends MushroomBaseCard implements LovelaceCard {
}

setConfig(config: CoverCardConfig): void {
this._config = {
super.setConfig({
tap_action: {
action: "toggle",
},
hold_action: {
action: "more-info",
},
...config,
};
});
this.updateActiveControl();
this.updatePosition();
}

private get _controls(): CoverCardControl[] {
if (!this._config || !this._stateObj) return [];
const controls: CoverCardControl[] = [];
if (this._config?.show_buttons_control) {
if (this._config.show_buttons_control) {
controls.push("buttons_control");
}
if (this._config?.show_position_control) {
if (this._config.show_position_control) {
controls.push("position_control");
}
if (this._config?.show_tilt_position_control) {
if (this._config.show_tilt_position_control) {
controls.push("tilt_position_control");
}
this._controls = controls;
this._activeControl = controls[0];
this.updatePosition();
return controls;
}

updateActiveControl() {
const isActiveControlSupported = this._activeControl
? this._controls.includes(this._activeControl)
: false;
this._activeControl = isActiveControlSupported ? this._activeControl : this._controls[0];
}

protected updated(changedProperties: PropertyValues) {
super.updated(changedProperties);
if (this.hass && changedProperties.has("hass")) {
this.updatePosition();
this.updateActiveControl();
}
}

Expand All @@ -127,10 +142,7 @@ export class CoverCard extends MushroomBaseCard implements LovelaceCard {

updatePosition() {
this.position = undefined;
if (!this._config || !this.hass || !this._config.entity) return;

const entityId = this._config.entity;
const stateObj = this.hass.states[entityId] as CoverEntity | undefined;
const stateObj = this._stateObj;

if (!stateObj) return;
this.position = getPosition(stateObj);
Expand All @@ -151,8 +163,7 @@ export class CoverCard extends MushroomBaseCard implements LovelaceCard {
return nothing;
}

const entityId = this._config.entity;
const stateObj = this.hass.states[entityId] as CoverEntity | undefined;
const stateObj = this._stateObj;

if (!stateObj) {
return this.renderNotFound(this._config);
Expand Down
Loading

0 comments on commit 5d72e3e

Please sign in to comment.