diff --git a/gallery/src/demos/demo-hui-conditional-card.js b/gallery/src/demos/demo-hui-conditional-card.js
new file mode 100644
index 0000000000..69288eee08
--- /dev/null
+++ b/gallery/src/demos/demo-hui-conditional-card.js
@@ -0,0 +1,84 @@
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
+
+import getEntity from '../data/entity.js';
+import provideHass from '../data/provide_hass.js';
+import '../components/demo-cards.js';
+
+const ENTITIES = [
+ getEntity('light', 'controller_1', 'on', {
+ friendly_name: 'Controller 1'
+ }),
+ getEntity('light', 'controller_2', 'on', {
+ friendly_name: 'Controller 2'
+ }),
+ getEntity('light', 'floor', 'off', {
+ friendly_name: 'Floor light'
+ }),
+ getEntity('light', 'kitchen', 'on', {
+ friendly_name: 'Kitchen light'
+ }),
+];
+
+const CONFIGS = [
+ {
+ heading: 'Controller',
+ config: `
+- type: entities
+ entities:
+ - light.controller_1
+ - light.controller_2
+ - type: divider
+ - light.floor
+ - light.kitchen
+ `
+ },
+ {
+ heading: 'Demo',
+ config: `
+- type: conditional
+ conditions:
+ - entity: light.controller_1
+ state: "on"
+ - entity: light.controller_2
+ state_not: "off"
+ card:
+ type: entities
+ entities:
+ - light.controller_1
+ - light.controller_2
+ - light.floor
+ - light.kitchen
+ `
+ },
+];
+
+class DemoConditional extends PolymerElement {
+ static get template() {
+ return html`
+
+ `;
+ }
+
+ static get properties() {
+ return {
+ _configs: {
+ type: Object,
+ value: CONFIGS
+ },
+ hass: Object,
+ };
+ }
+
+ ready() {
+ super.ready();
+ const hass = provideHass(this.$.demos);
+ hass.addEntities(ENTITIES);
+ }
+}
+
+customElements.define('demo-hui-conditional-card', DemoConditional);
diff --git a/src/panels/lovelace/cards/hui-conditional-card.js b/src/panels/lovelace/cards/hui-conditional-card.js
new file mode 100644
index 0000000000..0408fb6fd7
--- /dev/null
+++ b/src/panels/lovelace/cards/hui-conditional-card.js
@@ -0,0 +1,78 @@
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
+
+import computeCardSize from '../common/compute-card-size.js';
+import createCardElement from '../common/create-card-element.js';
+
+class HuiConditionalCard extends PolymerElement {
+ static get template() {
+ return html`
+
+
+ `;
+ }
+
+ static get properties() {
+ return {
+ hass: {
+ type: Object,
+ observer: '_hassChanged',
+ },
+ _config: Object
+ };
+ }
+
+ ready() {
+ super.ready();
+ if (this._config) this._buildConfig();
+ }
+
+ setConfig(config) {
+ if (!config || !config.card || !Array.isArray(config.conditions) ||
+ !config.conditions.every(c => c.entity && (c.state || c.state_not))) {
+ throw new Error('Error in card configuration.');
+ }
+
+ this._config = config;
+ if (this.$) this._buildConfig();
+ }
+
+ _buildConfig() {
+ const config = this._config;
+ const root = this.$.card;
+ while (root.lastChild) {
+ root.removeChild(root.lastChild);
+ }
+
+ const element = createCardElement(config.card);
+ element.hass = this.hass;
+ root.appendChild(element);
+ }
+
+ getCardSize() {
+ const el = this.$.card && this.$.card.lastChild;
+ return el ? computeCardSize(el) : 1;
+ }
+
+ _hassChanged(hass) {
+ const root = this.$.card;
+ if (!root || !root.lastChild) return;
+
+ root.lastChild.hass = hass;
+
+ const conditions = this._config.conditions;
+ const visible = conditions.every((c) => {
+ if (c.entity in hass.states) {
+ if (c.state) return hass.states[c.entity].state === c.state;
+ return hass.states[c.entity].state !== c.state_not;
+ }
+ return false;
+ });
+ root.classList.toggle('hidden', !visible);
+ }
+}
+customElements.define('hui-conditional-card', HuiConditionalCard);
diff --git a/src/panels/lovelace/common/create-card-element.js b/src/panels/lovelace/common/create-card-element.js
index b2495daad8..3f47536b93 100644
--- a/src/panels/lovelace/common/create-card-element.js
+++ b/src/panels/lovelace/common/create-card-element.js
@@ -1,5 +1,6 @@
import fireEvent from '../../../common/dom/fire_event.js';
+import '../cards/hui-conditional-card.js';
import '../cards/hui-entities-card.js';
import '../cards/hui-entity-filter-card.js';
import '../cards/hui-error-card.js';
@@ -20,7 +21,8 @@ import '../cards/hui-weather-forecast-card';
import createErrorCardConfig from './create-error-card-config.js';
-const CARD_TYPES = [
+const CARD_TYPES = new Set([
+ 'conditional',
'entities',
'entity-filter',
'error',
@@ -38,7 +40,7 @@ const CARD_TYPES = [
'plant-status',
'vertical-stack',
'weather-forecast'
-];
+]);
const CUSTOM_TYPE_PREFIX = 'custom:';
@@ -81,7 +83,7 @@ export default function createCardElement(config) {
return element;
}
- if (!CARD_TYPES.includes(config.type)) {
+ if (!CARD_TYPES.has(config.type)) {
return _createErrorElement(`Unknown card type encountered: ${config.type}.`, config);
}