Skip to content

Commit 9778a49

Browse files
authored
0.2.0 (#2)
* Add support for default values, number and boolean * Fix bug when no variable * Support for objects * Update documentation
1 parent a12ad22 commit 9778a49

7 files changed

+104
-47
lines changed

README.md

+37-15
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ This card is for [Lovelace](https://www.home-assistant.io/lovelace) on [Home Ass
1717

1818
We all use multiple times the same block of configuration across our lovelace configuration and we don't want to change the same things in a hundred places across our configuration each time we want to modify something.
1919

20-
`declutterring-card` to the rescue!! This card allows you to reuse multiple times the same configuration in your lovelace configuration to avoid repetition.
20+
`declutterring-card` to the rescue!! This card allows you to reuse multiple times the same configuration in your lovelace configuration to avoid repetition and supports variables and default values.
2121

2222
## Configuration
2323

@@ -27,29 +27,47 @@ First, you need to define your templates.
2727

2828
The templates are defined in an object at the root of your lovelace configuration. This object needs to be named `decluttering_templates`.
2929

30-
This object needs to contains your templates declaration, each template has a name and can contain variables. A variable needs to be enclosed in double square brackets `[[variable_name]]`. It will later be replaced by a real value when you instanciate a card which uses this template.
30+
This object needs to contains your templates declaration, each template has a name and can contain variables. A variable needs to be enclosed in double square brackets `[[variable_name]]`. It will later be replaced by a real value when you instanciate a card which uses this template. If a variable is alone on it's line, enclose it in single quotes: `'[[variable_name]]'`.
3131

32-
Eg in your `lovelace-ui.yaml`:
32+
You can also define default values for your variables in the `default` object.
33+
34+
```yaml
35+
decluttering_templates:
36+
<template_name>
37+
default: # This is optional
38+
- <variable_name>: <variable_value>
39+
- <variable_name>: <variable_value>
40+
[...]
41+
card: # This is where you put your card config (it can be a card embedding other cards)
42+
type: custom:my-super-card
43+
[...]
44+
```
45+
46+
Example in your `lovelace-ui.yaml`:
3347
```yaml
3448
resources:
3549
- url: /local/decluttering-card.js
3650
type: module
3751

3852
decluttering_templates:
3953
my_first_template: # This is the name of a template
40-
type: custom:button-card
41-
name: '[[name]]'
42-
icon: 'mdi:[[icon]]'
54+
default:
55+
- icon: fire
56+
card:
57+
type: custom:button-card
58+
name: '[[name]]'
59+
icon: 'mdi:[[icon]]'
4360

4461
my_second_template: # This is the name of another template
45-
type: custom:vertical-stack-in-card
46-
cards:
47-
- type: horizontal-stack
48-
cards:
49-
- type: custom:button-card
50-
entity: '[[entity_1]]'
51-
- type: custom:button-card
52-
entity: '[[entity_2]]'
62+
card:
63+
type: custom:vertical-stack-in-card
64+
cards:
65+
- type: horizontal-stack
66+
cards:
67+
- type: custom:button-card
68+
entity: '[[entity_1]]'
69+
- type: custom:button-card
70+
entity: '[[entity_2]]'
5371
```
5472
5573
### Using the card
@@ -66,7 +84,11 @@ Example which references the previous templates:
6684
template: my_first_template
6785
variables:
6886
- name: Test Button
69-
- icon: fire
87+
- icon: arrow-up
88+
89+
- type: custom:decluttering-card
90+
template: my_first_template
91+
variables: Default Icon Button
7092
7193
- type: custom:decluterring-card
7294
template: my_second_template

dist/decluttering-card.js

+11-6
Original file line numberDiff line numberDiff line change
@@ -183,25 +183,30 @@ var e = {},
183183
}return null;
184184
},
185185
v = (e, t) => {
186-
if (!e) return t;let n = JSON.stringify(t);return e.forEach(e => {
186+
if (!e && !t.default) return t.card;let n = [];e && (n = e.slice(0)), t.default && (n = n.concat(t.default));let o = JSON.stringify(t.card);return n.forEach(e => {
187187
const t = Object.keys(e)[0],
188-
o = Object.values(e)[0],
189-
r = new RegExp(`\\[\\[${t}\\]\\]`, "gm");n = n.replace(r, o);
190-
}), JSON.parse(n);
188+
n = Object.values(e)[0],
189+
r = new RegExp(`\\[\\[${t}\\]\\]`, "gm");if ("number" == typeof n || "boolean" == typeof n) {
190+
const e = new RegExp(`"\\[\\[${t}\\]\\]"`, "gm");o = o.replace(e, n);
191+
}if ("object" == typeof n) {
192+
const e = new RegExp(`"\\[\\[${t}\\]\\]"`, "gm"),
193+
r = JSON.stringify(n);o = o.replace(e, r);
194+
} else o = o.replace(r, n);
195+
}), JSON.parse(o);
191196
};customElements.define("decluttering-card", class extends HTMLElement {
192197
constructor() {
193198
super(), this.attachShadow({ mode: "open" });
194199
}set hass(e) {
195200
this._card && (this._card.hass = e);
196201
}setConfig(e) {
197-
if (!e.template) throw new Error("Missing template object in your config");const t = g();if (!t.config && !t.config.decluttering_templates) throw new Error("The object decluttering_templates doesn't exist in your main lovelace config.");const n = t.config.decluttering_templates[e.template];if (!n) throw new Error(`The template "${e.template}" doesn't exist in decluttering_templates`);const o = this.shadowRoot;for (; o && o.hasChildNodes();) o.removeChild(o.lastChild);const r = document.createElement("div");r.id = "root", o.appendChild(r);const i = (e, t) => {
202+
if (!e.template) throw new Error("Missing template object in your config");const t = g();if (!t.config && !t.config.decluttering_templates) throw new Error("The object decluttering_templates doesn't exist in your main lovelace config.");const n = t.config.decluttering_templates[e.template];if (!n || !n.card) throw new Error(`The template "${e.template}" doesn't exist in decluttering_templates`);const o = this.shadowRoot;for (; o && o.hasChildNodes();) o.removeChild(o.lastChild);const r = document.createElement("div");r.id = "root", o.appendChild(r);const i = (e, t) => {
198203
const n = document.createElement(e);try {
199204
n.setConfig(t);
200205
} catch (n) {
201206
return console.error(e, n), a(n.message, t);
202207
}return n;
203208
},
204-
a = (e, t) => i("hui-error-card", { type: "error", error: e, config: t });let s = n.type;if (s = s.startsWith("divider") ? "hui-divider-row" : s.startsWith("custom:") ? s.substr("custom:".length) : `hui-${s}-card`, customElements.get(s)) {
209+
a = (e, t) => i("hui-error-card", { type: "error", error: e, config: t });let s = n.card.type;if (s = s.startsWith("divider") ? "hui-divider-row" : s.startsWith("custom:") ? s.substr("custom:".length) : `hui-${s}-card`, customElements.get(s)) {
205210
const t = i(s, v(e.variables, n));r.appendChild(t), this._card = t;
206211
} else {
207212
const e = a(`Custom element doesn't exist: ${s}.`, n);e.style.display = "None";const t = setTimeout(() => {

package-lock.json

+18-10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,15 @@
3939
"eslint-plugin-import": "^2.17.2",
4040
"npm": "^6.9.0",
4141
"pre-commit": "^1.2.2",
42-
"prettier": "^1.17.1",
43-
"rollup": "^1.12.2",
42+
"prettier": "^1.18.2",
43+
"rollup": "^1.14.3",
4444
"rollup-plugin-babel": "^4.3.2",
4545
"rollup-plugin-json": "^4.0.0",
4646
"rollup-plugin-node-resolve": "^4.2.4",
4747
"rollup-plugin-terser": "^4.0.4",
4848
"rollup-plugin-typescript2": "^0.20.1",
4949
"ts-lit-plugin": "^1.0.6",
50-
"typescript": "^3.4.4",
50+
"typescript": "^3.5.1",
5151
"typescript-styled-plugin": "^0.14.0"
5252
},
5353
"dependencies": {

src/decluttering-card.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DeclutteringCardConfig } from './types';
1+
import { DeclutteringCardConfig, TemplateConfig } from './types';
22
import {
33
HomeAssistant,
44
getLovelace,
@@ -28,8 +28,8 @@ class DeclutteringCard extends HTMLElement {
2828
if (!ll.config && !ll.config.decluttering_templates) {
2929
throw new Error('The object decluttering_templates doesn\'t exist in your main lovelace config.');
3030
}
31-
const cardConfig = ll.config.decluttering_templates[config.template]
32-
if (!cardConfig) {
31+
const templateConfig = ll.config.decluttering_templates[config.template] as TemplateConfig;
32+
if (!templateConfig || !templateConfig.card) {
3333
throw new Error(`The template "${config.template}" doesn't exist in decluttering_templates`);
3434
}
3535

@@ -83,7 +83,7 @@ class DeclutteringCard extends HTMLElement {
8383
}
8484
}
8585

86-
let tag = cardConfig.type;
86+
let tag = templateConfig.card.type;
8787

8888
if (tag.startsWith("divider")) {
8989
tag = `hui-divider-row`;
@@ -94,14 +94,14 @@ class DeclutteringCard extends HTMLElement {
9494
}
9595

9696
if (customElements.get(tag)) {
97-
const element = _createThing(tag, deepReplace(config.variables, cardConfig));
97+
const element = _createThing(tag, deepReplace(config.variables, templateConfig));
9898
main!.appendChild(element);
9999
this._card = element;
100100
} else {
101101
// If element doesn't exist (yet) create an error
102102
const element = _createError(
103103
`Custom element doesn't exist: ${tag}.`,
104-
cardConfig
104+
templateConfig
105105
);
106106
element.style.display = "None";
107107

src/deep-replace.ts

+24-7
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,35 @@
1-
import { VariablesConfig } from "./types";
1+
import { VariablesConfig, TemplateConfig } from "./types";
22

33
export default (
44
variables: VariablesConfig[] | undefined,
5-
cardConfig: any,
5+
templateConfig: TemplateConfig,
66
): any => {
7-
if (!variables) {
8-
return cardConfig;
7+
if (!variables && !templateConfig.default) {
8+
return templateConfig.card;
99
}
10-
let jsonConfig = JSON.stringify(cardConfig);
11-
variables.forEach(variable => {
10+
let variableArray: VariablesConfig[] = [];
11+
if (variables) {
12+
variableArray = variables.slice(0);
13+
}
14+
if (templateConfig.default) {
15+
variableArray = variableArray.concat(templateConfig.default);
16+
}
17+
let jsonConfig = JSON.stringify(templateConfig.card);
18+
variableArray.forEach(variable => {
1219
const key = Object.keys(variable)[0];
1320
const value = Object.values(variable)[0];
1421
const rxp = new RegExp(`\\[\\[${key}\\]\\]`, "gm");
15-
jsonConfig = jsonConfig.replace(rxp, value);
22+
if (typeof value === 'number' || typeof value === 'boolean') {
23+
const rxp2 = new RegExp(`"\\[\\[${key}\\]\\]"`, "gm");
24+
jsonConfig = jsonConfig.replace(rxp2, (value as unknown as string));
25+
}
26+
if (typeof value === 'object') {
27+
const rxp2 = new RegExp(`"\\[\\[${key}\\]\\]"`, "gm");
28+
const valueString = JSON.stringify(value);
29+
jsonConfig = jsonConfig.replace(rxp2, valueString);
30+
} else {
31+
jsonConfig = jsonConfig.replace(rxp, value);
32+
}
1633
});
1734
return JSON.parse(jsonConfig);
1835
}

src/types.ts

+5
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,8 @@ export interface DeclutteringCardConfig {
66
export interface VariablesConfig {
77
[key: string]: any;
88
}
9+
10+
export interface TemplateConfig {
11+
default: VariablesConfig[];
12+
card: any;
13+
}

0 commit comments

Comments
 (0)