mirror of
https://github.com/home-assistant/developers.home-assistant.git
synced 2025-07-15 13:26:28 +00:00
Add custom tile features documentation (#1680)
* Add custom tile features documentation * Feedbacks
This commit is contained in:
parent
59ab7df279
commit
838db3fad4
@ -22,12 +22,12 @@ class ContentCardExample extends HTMLElement {
|
|||||||
<div class="card-content"></div>
|
<div class="card-content"></div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
`;
|
`;
|
||||||
this.content = this.querySelector('div');
|
this.content = this.querySelector("div");
|
||||||
}
|
}
|
||||||
|
|
||||||
const entityId = this.config.entity;
|
const entityId = this.config.entity;
|
||||||
const state = hass.states[entityId];
|
const state = hass.states[entityId];
|
||||||
const stateStr = state ? state.state : 'unavailable';
|
const stateStr = state ? state.state : "unavailable";
|
||||||
|
|
||||||
this.content.innerHTML = `
|
this.content.innerHTML = `
|
||||||
The state of ${entityId} is ${stateStr}!
|
The state of ${entityId} is ${stateStr}!
|
||||||
@ -40,7 +40,7 @@ class ContentCardExample extends HTMLElement {
|
|||||||
// will render an error card.
|
// will render an error card.
|
||||||
setConfig(config) {
|
setConfig(config) {
|
||||||
if (!config.entity) {
|
if (!config.entity) {
|
||||||
throw new Error('You need to define an entity');
|
throw new Error("You need to define an entity");
|
||||||
}
|
}
|
||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
@ -52,7 +52,7 @@ class ContentCardExample extends HTMLElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('content-card-example', ContentCardExample);
|
customElements.define("content-card-example", ContentCardExample);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Referencing your new card
|
## Referencing your new card
|
||||||
@ -66,7 +66,7 @@ You can then use your card in your dashboard configuration:
|
|||||||
```yaml
|
```yaml
|
||||||
# Example dashboard configuration
|
# Example dashboard configuration
|
||||||
views:
|
views:
|
||||||
- name: Example
|
- name: Example
|
||||||
cards:
|
cards:
|
||||||
- type: "custom:content-card-example"
|
- type: "custom:content-card-example"
|
||||||
entity: input_boolean.switch_tv
|
entity: input_boolean.switch_tv
|
||||||
@ -85,7 +85,7 @@ Your card can define a `getCardSize` method that returns the size of your card a
|
|||||||
Since some elements can be lazy loaded, if you want to get the card size of another element, you should first check it is defined.
|
Since some elements can be lazy loaded, if you want to get the card size of another element, you should first check it is defined.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
return customElements
|
return customElements
|
||||||
.whenDefined(element.localName)
|
.whenDefined(element.localName)
|
||||||
.then(() => element.getCardSize());
|
.then(() => element.getCardSize());
|
||||||
```
|
```
|
||||||
@ -106,7 +106,7 @@ import "https://unpkg.com/wired-toggle@0.8.0/wired-toggle.js?module";
|
|||||||
import {
|
import {
|
||||||
LitElement,
|
LitElement,
|
||||||
html,
|
html,
|
||||||
css
|
css,
|
||||||
} from "https://unpkg.com/lit-element@2.0.1/lit-element.js?module";
|
} from "https://unpkg.com/lit-element@2.0.1/lit-element.js?module";
|
||||||
|
|
||||||
function loadCSS(url) {
|
function loadCSS(url) {
|
||||||
@ -123,14 +123,14 @@ class WiredToggleCard extends LitElement {
|
|||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
hass: {},
|
hass: {},
|
||||||
config: {}
|
config: {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<wired-card elevation="2">
|
<wired-card elevation="2">
|
||||||
${this.config.entities.map(ent => {
|
${this.config.entities.map((ent) => {
|
||||||
const stateObj = this.hass.states[ent];
|
const stateObj = this.hass.states[ent];
|
||||||
return stateObj
|
return stateObj
|
||||||
? html`
|
? html`
|
||||||
@ -138,13 +138,11 @@ class WiredToggleCard extends LitElement {
|
|||||||
${stateObj.attributes.friendly_name}
|
${stateObj.attributes.friendly_name}
|
||||||
<wired-toggle
|
<wired-toggle
|
||||||
.checked="${stateObj.state === "on"}"
|
.checked="${stateObj.state === "on"}"
|
||||||
@change="${ev => this._toggle(stateObj)}"
|
@change="${(ev) => this._toggle(stateObj)}"
|
||||||
></wired-toggle>
|
></wired-toggle>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: html`
|
: html` <div class="not-found">Entity ${ent} not found.</div> `;
|
||||||
<div class="not-found">Entity ${ent} not found.</div>
|
|
||||||
`;
|
|
||||||
})}
|
})}
|
||||||
</wired-card>
|
</wired-card>
|
||||||
`;
|
`;
|
||||||
@ -165,7 +163,7 @@ class WiredToggleCard extends LitElement {
|
|||||||
|
|
||||||
_toggle(state) {
|
_toggle(state) {
|
||||||
this.hass.callService("homeassistant", "toggle", {
|
this.hass.callService("homeassistant", "toggle", {
|
||||||
entity_id: state.entity_id
|
entity_id: state.entity_id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +206,7 @@ And for your configuration:
|
|||||||
```yaml
|
```yaml
|
||||||
# Example dashboard configuration
|
# Example dashboard configuration
|
||||||
views:
|
views:
|
||||||
- name: Example
|
- name: Example
|
||||||
cards:
|
cards:
|
||||||
- type: "custom:wired-toggle-card"
|
- type: "custom:wired-toggle-card"
|
||||||
entities:
|
entities:
|
||||||
@ -248,7 +246,6 @@ customElements.define('content-card-example', ContentCardExample);
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
class ContentCardEditor extends LitElement {
|
class ContentCardEditor extends LitElement {
|
||||||
|
|
||||||
setConfig(config) {
|
setConfig(config) {
|
||||||
this._config = config;
|
this._config = config;
|
||||||
}
|
}
|
||||||
@ -256,9 +253,9 @@ class ContentCardEditor extends LitElement {
|
|||||||
configChanged(newConfig) {
|
configChanged(newConfig) {
|
||||||
const event = new Event("config-changed", {
|
const event = new Event("config-changed", {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
composed: true
|
composed: true,
|
||||||
});
|
});
|
||||||
event.detail = {config: newConfig};
|
event.detail = { config: newConfig };
|
||||||
this.dispatchEvent(event);
|
this.dispatchEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -269,10 +266,125 @@ window.customCards.push({
|
|||||||
type: "content-card-example",
|
type: "content-card-example",
|
||||||
name: "Content Card",
|
name: "Content Card",
|
||||||
preview: false, // Optional - defaults to false
|
preview: false, // Optional - defaults to false
|
||||||
description: "A custom card made by me!" // Optional
|
description: "A custom card made by me!", // Optional
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Tile features
|
||||||
|
|
||||||
|
The tile card has support for "features" to add quick actions to control the entity. We offer some built-in features, but you can build and use your own using similar way than defining custom cards.
|
||||||
|
|
||||||
|
Below is an example of a custom tile feature for [button entity](/docs/core/entity/button/).
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```js
|
||||||
|
import {
|
||||||
|
LitElement,
|
||||||
|
html,
|
||||||
|
css,
|
||||||
|
} from "https://unpkg.com/lit-element@2.0.1/lit-element.js?module";
|
||||||
|
|
||||||
|
const supportsButtonPressTileFeature = (stateObj) => {
|
||||||
|
const domain = stateObj.entity_id.split(".")[0];
|
||||||
|
return domain === "button";
|
||||||
|
};
|
||||||
|
|
||||||
|
class ButtonPressTileFeature extends LitElement {
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
hass: undefined,
|
||||||
|
config: undefined,
|
||||||
|
stateObj: undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static getStubConfig() {
|
||||||
|
return {
|
||||||
|
type: "custom:button-press-tile-feature",
|
||||||
|
label: "Press",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
setConfig(config) {
|
||||||
|
if (!config) {
|
||||||
|
throw new Error("Invalid configuration");
|
||||||
|
}
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
_press(ev) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
this.hass.callService("button", "press", {
|
||||||
|
entity_id: this.stateObj.entity_id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (
|
||||||
|
!this.config ||
|
||||||
|
!this.hass ||
|
||||||
|
!this.stateObj ||
|
||||||
|
!supportsButtonPressTileFeature(this.stateObj)
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<div class="container">
|
||||||
|
<button class="button" @click=${this._press}>
|
||||||
|
${this.config.label || "Press"}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return css`
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
padding: 0 12px 12px 12px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
.button {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: none;
|
||||||
|
background-color: #eeeeee;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 180ms ease-in-out;
|
||||||
|
}
|
||||||
|
.button:hover {
|
||||||
|
background-color: #dddddd;
|
||||||
|
}
|
||||||
|
.button:focus {
|
||||||
|
background-color: #cdcdcd;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define("button-press-tile-feature", ButtonPressTileFeature);
|
||||||
|
|
||||||
|
window.customTileFeatures = window.customTileFeatures || [];
|
||||||
|
window.customTileFeatures.push({
|
||||||
|
type: "button-press-tile-feature",
|
||||||
|
name: "Button press",
|
||||||
|
supported: supportsButtonPressTileFeature, // Optional
|
||||||
|
configurable: true, // Optional - defaults to false
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
The only difference with custom cards is the graphical configuration option.
|
||||||
|
To have it displayed in the tile card editor, you must add an object describing it to the array `window.customTileFeatures`.
|
||||||
|
|
||||||
|
Required properties of the object are `type` and `name`. It is recommended to define the `supported` option with a function so the editor can only propose the feature if it is compatible with the selected entity in the tile card. Set `configurable` to `true` if your entity has additional configuration (e.g. `label` option in the example above) so the editor.
|
||||||
|
|
||||||
|
Also, the static functions `getConfigElement` and `getStubConfig` work the same as with normal custom maps.
|
||||||
|
|
||||||
## Advanced Resources
|
## Advanced Resources
|
||||||
|
|
||||||
Community Maintained Boilerplate Card - Advanced Template (Typescript, Rollup, Linting, etc.)
|
Community Maintained Boilerplate Card - Advanced Template (Typescript, Rollup, Linting, etc.)
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 7.5 KiB |
Loading…
x
Reference in New Issue
Block a user