From 882e79524bc75d970a68fc2b628de718fca3acfa Mon Sep 17 00:00:00 2001 From: Marc Randolph Date: Sun, 2 Jan 2022 10:32:12 -0600 Subject: [PATCH 001/127] Spelling fix ('a NFC tag' to 'an NFC tag') (#11073) --- src/translations/en.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/translations/en.json b/src/translations/en.json index d2155fe09c..3a6d224254 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -972,7 +972,7 @@ }, "tags": { "title": "Tags", - "description": "Trigger automations when a NFC tag, QR code, etc. is scanned" + "description": "Trigger automations when an NFC tag, QR code, etc. is scanned" }, "people": { "title": "People & Zones", @@ -1037,7 +1037,7 @@ }, "tag": { "caption": "Tags", - "description": "Trigger automations when a NFC tag, QR code, etc. is scanned", + "description": "Trigger automations when an NFC tag, QR code, etc. is scanned", "learn_more": "Learn more about tags", "no_tags": "No tags", "add_tag": "Add tag", From 76a4b1efbd2b0479d409ff370d39fcfed598f302 Mon Sep 17 00:00:00 2001 From: OzGav Date: Mon, 3 Jan 2022 02:35:43 +1000 Subject: [PATCH 002/127] Update "electricitymap.com" app URL in `hui-energy-distribution-card` (#11040) --- .../lovelace/cards/energy/hui-energy-distribution-card.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts b/src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts index 20692e5ec2..58e49fe765 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts @@ -204,7 +204,7 @@ class HuiEnergyDistrubutionCard let homeHighCarbonCircumference: number | undefined; // This fallback is used in the demo - let electricityMapUrl = "https://www.electricitymap.org"; + let electricityMapUrl = "https://app.electricitymap.org"; if (this._data.co2SignalEntity && this._data.fossilEnergyConsumption) { // Calculate high carbon consumption From e3d78d6dc5d8af0b4d2cb860954b6a6262b9f67c Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 5 Jan 2022 12:49:05 -0800 Subject: [PATCH 003/127] Convert ha-gallery to TS (#11102) * Convert ha-gallery to TS * Prepare gallery to be design portal * Import card in introduction * Clean up demo IDs * Convert demo-cards * TypeScript conversion of demo-card * Fix default demo --- build-scripts/gulp/gallery.js | 2 +- gallery/src/components/demo-card.js | 129 ---------- gallery/src/components/demo-card.ts | 129 ++++++++++ gallery/src/components/demo-cards.js | 83 ------- gallery/src/components/demo-cards.ts | 92 +++++++ gallery/src/demos/demo-hui-iframe-card.ts | 12 +- ...r-rows.ts => demo-hui-media-player-row.ts} | 2 +- gallery/src/demos/demo-introduction.ts | 43 ++++ gallery/src/ha-gallery.js | 225 ------------------ gallery/src/ha-gallery.ts | 207 ++++++++++++++++ package.json | 2 + src/managers/notification-manager.ts | 4 + yarn.lock | 62 ++++- 13 files changed, 550 insertions(+), 442 deletions(-) delete mode 100644 gallery/src/components/demo-card.js create mode 100644 gallery/src/components/demo-card.ts delete mode 100644 gallery/src/components/demo-cards.js create mode 100644 gallery/src/components/demo-cards.ts rename gallery/src/demos/{demo-hui-media-player-rows.ts => demo-hui-media-player-row.ts} (97%) create mode 100644 gallery/src/demos/demo-introduction.ts delete mode 100644 gallery/src/ha-gallery.js create mode 100644 gallery/src/ha-gallery.ts diff --git a/build-scripts/gulp/gallery.js b/build-scripts/gulp/gallery.js index 2823ad70b1..9522d48b5c 100644 --- a/build-scripts/gulp/gallery.js +++ b/build-scripts/gulp/gallery.js @@ -25,7 +25,7 @@ gulp.task("gather-gallery-demos", async function gatherDemos() { for (const file of files) { const demoId = path.basename(file, ".ts"); const demoPath = "../src/demos/" + demoId; - content += ` "${demoId}": () => import("${demoPath}"),\n`; + content += ` "${demoId.substring(5)}": () => import("${demoPath}"),\n`; } content += "};"; diff --git a/gallery/src/components/demo-card.js b/gallery/src/components/demo-card.js deleted file mode 100644 index 4d9ce53899..0000000000 --- a/gallery/src/components/demo-card.js +++ /dev/null @@ -1,129 +0,0 @@ -import { html } from "@polymer/polymer/lib/utils/html-tag"; -/* eslint-plugin-disable lit */ -import { PolymerElement } from "@polymer/polymer/polymer-element"; -import { load } from "js-yaml"; -import { createCardElement } from "../../../src/panels/lovelace/create-element/create-card-element"; - -class DemoCard extends PolymerElement { - static get template() { - return html` - -

- [[config.heading]] - -

-
-
- -
- `; - } - - static get properties() { - return { - hass: { - type: Object, - observer: "_hassChanged", - }, - config: { - type: Object, - observer: "_configChanged", - }, - showConfig: Boolean, - _size: { - type: Number, - }, - }; - } - - ready() { - super.ready(); - } - - _configChanged(config) { - const card = this.$.card; - while (card.lastChild) { - card.removeChild(card.lastChild); - } - - const el = this._createCardElement(load(config.config)[0]); - card.appendChild(el); - this._getSize(el); - } - - async _getSize(el) { - await customElements.whenDefined(el.localName); - - if (!("getCardSize" in el)) { - this._size = undefined; - return; - } - this._size = await el.getCardSize(); - } - - _createCardElement(cardConfig) { - const element = createCardElement(cardConfig); - if (this.hass) { - element.hass = this.hass; - } - element.addEventListener( - "ll-rebuild", - (ev) => { - ev.stopPropagation(); - this._rebuildCard(element, cardConfig); - }, - { once: true } - ); - return element; - } - - _rebuildCard(cardElToReplace, config) { - const newCardEl = this._createCardElement(config); - cardElToReplace.parentElement.replaceChild(newCardEl, cardElToReplace); - } - - _hassChanged(hass) { - const card = this.$.card.lastChild; - if (card) card.hass = hass; - } - - _trim(config) { - return config.trim(); - } -} - -customElements.define("demo-card", DemoCard); diff --git a/gallery/src/components/demo-card.ts b/gallery/src/components/demo-card.ts new file mode 100644 index 0000000000..1c08792952 --- /dev/null +++ b/gallery/src/components/demo-card.ts @@ -0,0 +1,129 @@ +import { load } from "js-yaml"; +import { html, css, LitElement, PropertyValues } from "lit"; +import { customElement, property, query, state } from "lit/decorators"; +import { createCardElement } from "../../../src/panels/lovelace/create-element/create-card-element"; +import { HomeAssistant } from "../../../src/types"; + +export interface DemoCardConfig { + heading: string; + config: string; +} + +@customElement("demo-card") +class DemoCard extends LitElement { + @property() public hass!: HomeAssistant; + + @property() public config!: DemoCardConfig; + + @property() public showConfig = false; + + @state() private _size?: number; + + @query("#card") private _card!: HTMLElement; + + render() { + return html` +

+ ${this.config.heading} + ${this._size !== undefined + ? html`(size ${this._size})` + : ""} +

+
+
+ ${this.showConfig ? html`
${this.config.config.trim()}
` : ""} +
+ `; + } + + updated(changedProps: PropertyValues) { + super.updated(changedProps); + + if (changedProps.has("config")) { + const card = this._card; + while (card.lastChild) { + card.removeChild(card.lastChild); + } + + const el = this._createCardElement((load(this.config.config) as any)[0]); + card.appendChild(el); + this._getSize(el); + } + + if (changedProps.has("hass")) { + const card = this._card.lastChild; + if (card) { + (card as any).hass = this.hass; + } + } + } + + async _getSize(el) { + await customElements.whenDefined(el.localName); + + if (!("getCardSize" in el)) { + this._size = undefined; + return; + } + this._size = await el.getCardSize(); + } + + _createCardElement(cardConfig) { + const element = createCardElement(cardConfig); + if (this.hass) { + element.hass = this.hass; + } + element.addEventListener( + "ll-rebuild", + (ev) => { + ev.stopPropagation(); + this._rebuildCard(element, cardConfig); + }, + { once: true } + ); + return element; + } + + _rebuildCard(cardElToReplace, config) { + const newCardEl = this._createCardElement(config); + cardElToReplace.parentElement.replaceChild(newCardEl, cardElToReplace); + } + + static styles = css` + .root { + display: flex; + } + h2 { + margin: 0 0 20px; + color: var(--primary-color); + } + h2 small { + font-size: 0.5em; + color: var(--primary-text-color); + } + #card { + max-width: 400px; + width: 100vw; + } + pre { + width: 400px; + margin: 0 16px; + overflow: auto; + color: var(--primary-text-color); + } + @media only screen and (max-width: 800px) { + .root { + flex-direction: column; + } + pre { + margin: 16px 0; + } + } + `; +} + +declare global { + interface HTMLElementTagNameMap { + "demo-card": DemoCard; + } +} diff --git a/gallery/src/components/demo-cards.js b/gallery/src/components/demo-cards.js deleted file mode 100644 index 59faa671a6..0000000000 --- a/gallery/src/components/demo-cards.js +++ /dev/null @@ -1,83 +0,0 @@ -import "@polymer/app-layout/app-toolbar/app-toolbar"; -import { html } from "@polymer/polymer/lib/utils/html-tag"; -/* eslint-plugin-disable lit */ -import { PolymerElement } from "@polymer/polymer/polymer-element"; -import { applyThemesOnElement } from "../../../src/common/dom/apply_themes_on_element"; -import "../../../src/components/ha-formfield"; -import "../../../src/components/ha-switch"; -import "./demo-card"; - -class DemoCards extends PolymerElement { - static get template() { - return html` - - -
- - - - - - - -
-
-
-
- -
-
- `; - } - - static get properties() { - return { - configs: Object, - hass: Object, - _showConfig: { - type: Boolean, - value: false, - }, - }; - } - - _showConfigToggled(ev) { - this._showConfig = ev.target.checked; - } - - _darkThemeToggled(ev) { - applyThemesOnElement(this.$.container, { themes: {} }, "default", { - dark: ev.target.checked, - }); - } -} - -customElements.define("demo-cards", DemoCards); diff --git a/gallery/src/components/demo-cards.ts b/gallery/src/components/demo-cards.ts new file mode 100644 index 0000000000..609577e7f1 --- /dev/null +++ b/gallery/src/components/demo-cards.ts @@ -0,0 +1,92 @@ +import "@polymer/app-layout/app-toolbar/app-toolbar"; +import { html, css, LitElement } from "lit"; +import { customElement, property, query, state } from "lit/decorators"; +import { applyThemesOnElement } from "../../../src/common/dom/apply_themes_on_element"; +import "../../../src/components/ha-formfield"; +import "../../../src/components/ha-switch"; +import { HomeAssistant } from "../../../src/types"; +import "./demo-card"; +import type { DemoCardConfig } from "./demo-card"; + +@customElement("demo-cards") +class DemoCards extends LitElement { + @property() public configs!: DemoCardConfig[]; + + @property() public hass!: HomeAssistant; + + @state() private _showConfig = false; + + @query("#container") private _container!: HTMLElement; + + render() { + return html` + +
+ + + + + + + +
+
+
+
+ ${this.configs.map( + (config) => html` + + ` + )} +
+
+ `; + } + + _showConfigToggled(ev) { + this._showConfig = ev.target.checked; + } + + _darkThemeToggled(ev) { + applyThemesOnElement(this._container, { themes: {} } as any, "default", { + dark: ev.target.checked, + }); + } + + static styles = css` + #container { + min-height: calc(100vh - 128px); + background: var(--primary-background-color); + } + .cards { + display: flex; + flex-wrap: wrap; + justify-content: center; + } + demo-card { + margin: 16px 16px 32px; + } + app-toolbar { + background-color: var(--light-primary-color); + } + .filters { + margin-left: 60px; + } + ha-formfield { + margin-right: 16px; + } + `; +} + +declare global { + interface HTMLElementTagNameMap { + "demo-cards": DemoCards; + } +} diff --git a/gallery/src/demos/demo-hui-iframe-card.ts b/gallery/src/demos/demo-hui-iframe-card.ts index 811d858e44..32d7e39140 100644 --- a/gallery/src/demos/demo-hui-iframe-card.ts +++ b/gallery/src/demos/demo-hui-iframe-card.ts @@ -1,5 +1,6 @@ -import { html, LitElement, TemplateResult } from "lit"; -import { customElement } from "lit/decorators"; +import { html, LitElement, PropertyValues, TemplateResult } from "lit"; +import { customElement, query } from "lit/decorators"; +import { provideHass } from "../../../src/fake_data/provide_hass"; import "../components/demo-cards"; const CONFIGS = [ @@ -38,9 +39,16 @@ const CONFIGS = [ @customElement("demo-hui-iframe-card") class DemoIframe extends LitElement { + @query("demo-cards") private _demos!: HTMLElement; + protected render(): TemplateResult { return html``; } + + protected firstUpdated(changedProperties: PropertyValues) { + super.firstUpdated(changedProperties); + provideHass(this._demos); + } } declare global { diff --git a/gallery/src/demos/demo-hui-media-player-rows.ts b/gallery/src/demos/demo-hui-media-player-row.ts similarity index 97% rename from gallery/src/demos/demo-hui-media-player-rows.ts rename to gallery/src/demos/demo-hui-media-player-row.ts index 988d232e49..f99b20fcdf 100644 --- a/gallery/src/demos/demo-hui-media-player-rows.ts +++ b/gallery/src/demos/demo-hui-media-player-row.ts @@ -73,6 +73,6 @@ class DemoHuiMediaPlayerRow extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-media-player-row": DemoHuiMediaPlayerRow; + "demo-hui-media-player-rows": DemoHuiMediaPlayerRow; } } diff --git a/gallery/src/demos/demo-introduction.ts b/gallery/src/demos/demo-introduction.ts new file mode 100644 index 0000000000..29e306bbff --- /dev/null +++ b/gallery/src/demos/demo-introduction.ts @@ -0,0 +1,43 @@ +import { css, html, LitElement, TemplateResult } from "lit"; +import { customElement } from "lit/decorators"; +import "../../../src/components/ha-card"; +import "../../../src/components/ha-markdown"; + +@customElement("demo-introduction") +export class DemoIntroduction extends LitElement { + protected render(): TemplateResult { + return html` + +
+ +
+
+ `; + } + + static get styles() { + return css` + ha-card { + max-width: 600px; + margin: 24px auto; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "demo-introduction": DemoIntroduction; + } +} diff --git a/gallery/src/ha-gallery.js b/gallery/src/ha-gallery.js deleted file mode 100644 index 671cbe9077..0000000000 --- a/gallery/src/ha-gallery.js +++ /dev/null @@ -1,225 +0,0 @@ -import "@polymer/app-layout/app-header-layout/app-header-layout"; -import "@polymer/app-layout/app-header/app-header"; -import "@polymer/app-layout/app-toolbar/app-toolbar"; -import "@polymer/paper-item/paper-item"; -import "@polymer/paper-item/paper-item-body"; -import { html } from "@polymer/polymer/lib/utils/html-tag"; -/* eslint-plugin-disable lit */ -import { PolymerElement } from "@polymer/polymer/polymer-element"; -import "../../src/components/ha-card"; -import "../../src/components/ha-icon"; -import "../../src/components/ha-icon-button"; -import "../../src/managers/notification-manager"; -import "../../src/styles/polymer-ha-style"; -// eslint-disable-next-line import/extensions -import { DEMOS } from "../build/import-demos"; - -class HaGallery extends PolymerElement { - static get template() { - return html` - - - - - - - - -
- [[_withDefault(_demo, "Home Assistant Gallery")]] -
-
-
- -
-
- -
-
- - `; - } - - static get properties() { - return { - _fakeHass: { - type: Object, - // Just enough for computeRTL - value: { - language: "en", - translationMetadata: { - translations: {}, - }, - }, - }, - _demo: { - type: String, - value: document.location.hash.substr(1), - observer: "_demoChanged", - }, - _demos: { - type: Array, - value: Object.keys(DEMOS), - }, - _lovelaceDemos: { - type: Array, - computed: "_computeLovelace(_demos)", - }, - _restDemos: { - type: Array, - computed: "_computeRest(_demos)", - }, - }; - } - - ready() { - super.ready(); - - this.addEventListener("show-notification", (ev) => - this.$.notifications.showDialog({ message: ev.detail.message }) - ); - - this.addEventListener("alert-dismissed-clicked", () => - this.$.notifications.showDialog({ message: "Alert dismissed clicked" }) - ); - this.addEventListener("hass-more-info", (ev) => { - if (ev.detail.entityId) { - this.$.notifications.showDialog({ - message: `Showing more info for ${ev.detail.entityId}`, - }); - } - }); - - window.addEventListener("hashchange", () => { - this._demo = document.location.hash.substr(1); - }); - } - - _withDefault(value, def) { - return value || def; - } - - _demoChanged(demo) { - const root = this.$.demo; - - while (root.lastChild) root.removeChild(root.lastChild); - - if (demo) { - DEMOS[demo](); - const el = document.createElement(demo); - root.appendChild(el); - } - } - - _computeHeaderButtonClass(demo) { - return demo ? "" : "invisible"; - } - - _backTapped() { - document.location.hash = ""; - } - - _computeLovelace(demos) { - return demos.filter((demo) => demo.includes("hui")); - } - - _computeRest(demos) { - return demos.filter((demo) => !demo.includes("hui")); - } -} - -customElements.define("ha-gallery", HaGallery); diff --git a/gallery/src/ha-gallery.ts b/gallery/src/ha-gallery.ts new file mode 100644 index 0000000000..d7d38b2381 --- /dev/null +++ b/gallery/src/ha-gallery.ts @@ -0,0 +1,207 @@ +import { mdiMenu } from "@mdi/js"; +import "@material/mwc-drawer"; +import "@material/mwc-top-app-bar-fixed"; +import { html, css, LitElement, PropertyValues } from "lit"; +import { customElement, property, query } from "lit/decorators"; +import "../../src/components/ha-icon-button"; +import "../../src/managers/notification-manager"; +import { haStyle } from "../../src/resources/styles"; +// eslint-disable-next-line import/extensions +import { DEMOS } from "../build/import-demos"; +import { dynamicElement } from "../../src/common/dom/dynamic-element-directive"; + +const DEMOS_GROUPED: { + header?: string; + demos?: string[]; + demoStart?: string; +}[] = [ + { + demos: ["introduction"], + }, + { + header: "Lovelace", + demoStart: "hui-", + }, + { + header: "Automation", + demoStart: "automation-", + }, + { + header: "Rest", + demoStart: "", + }, +]; + +const demosToProcess = new Set(Object.keys(DEMOS)); + +for (const group of Object.values(DEMOS_GROUPED)) { + if (group.demos) { + for (const demo of group.demos) { + demosToProcess.delete(demo); + } + } + if (!group.demos) { + group.demos = []; + } + if (group.demoStart !== undefined) { + for (const demo of demosToProcess) { + if (demo.startsWith(group.demoStart)) { + group.demos.push(demo); + demosToProcess.delete(demo); + } + } + } +} + +const FAKE_HASS = { + // Just enough for computeRTL for notification-manager + language: "en", + translationMetadata: { + translations: {}, + }, +}; + +@customElement("ha-gallery") +class HaGallery extends LitElement { + @property() private _demo = + document.location.hash.substring(1) || DEMOS_GROUPED[0].demos![0]; + + @query("notification-manager") + private _notifications!: HTMLElementTagNameMap["notification-manager"]; + + @query("mwc-drawer") + private _drawer!: HTMLElementTagNameMap["mwc-drawer"]; + + render() { + return html` + + Home Assistant Design + + +
+ + + +
${this._demo}
+
+
${dynamicElement(`demo-${this._demo}`)}
+
+
+ + `; + } + + private _renderDemo(demo: string, demoStart?: string) { + return html` + ${demoStart === undefined ? demo : demo.substring(demoStart.length)} + `; + } + + firstUpdated(changedProps: PropertyValues) { + super.firstUpdated(changedProps); + + this.addEventListener("show-notification", (ev) => + this._notifications.showDialog({ message: ev.detail.message }) + ); + + this.addEventListener("alert-dismissed-clicked", () => + this._notifications.showDialog({ message: "Alert dismissed clicked" }) + ); + this.addEventListener("hass-more-info", (ev) => { + if (ev.detail.entityId) { + this._notifications.showDialog({ + message: `Showing more info for ${ev.detail.entityId}`, + }); + } + }); + + document.location.hash = this._demo; + + window.addEventListener("hashchange", () => { + this._demo = document.location.hash.substring(1); + }); + } + + updated(changedProps: PropertyValues) { + super.updated(changedProps); + if (changedProps.has("_demo") && this._demo) { + DEMOS[this._demo](); + } + } + + _menuTapped() { + this._drawer.open = !this._drawer.open; + } + + static styles = [ + haStyle, + css` + :host { + -ms-user-select: initial; + -webkit-user-select: initial; + -moz-user-select: initial; + } + + .section { + font-weight: bold; + } + + .sidebar { + padding: 4px; + } + + .sidebar p { + margin: 1em 12px; + } + + .sidebar a { + color: var(--primary-text-color); + display: block; + padding: 4px 12px; + text-decoration: none; + position: relative; + } + + .sidebar a[active]::before { + border-radius: 4px; + position: absolute; + top: 0; + right: 2px; + bottom: 0; + left: 2px; + pointer-events: none; + content: ""; + transition: opacity 15ms linear; + will-change: opacity; + background-color: var(--sidebar-selected-icon-color); + opacity: 0.12; + } + `, + ]; +} + +declare global { + interface HTMLElementTagNameMap { + "ha-gallery": HaGallery; + } +} diff --git a/package.json b/package.json index 74a38b6ab1..0c0125cb79 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "@material/mwc-checkbox": "0.25.3", "@material/mwc-circular-progress": "0.25.3", "@material/mwc-dialog": "0.25.3", + "@material/mwc-drawer": "^0.25.3", "@material/mwc-fab": "0.25.3", "@material/mwc-formfield": "0.25.3", "@material/mwc-icon-button": "patch:@material/mwc-icon-button@0.25.3#./.yarn/patches/@material/mwc-icon-button/remove-icon.patch", @@ -66,6 +67,7 @@ "@material/mwc-tab": "0.25.3", "@material/mwc-tab-bar": "0.25.3", "@material/mwc-textfield": "0.25.3", + "@material/mwc-top-app-bar-fixed": "^0.25.3", "@material/top-app-bar": "14.0.0-canary.261f2db59.0", "@mdi/js": "6.5.95", "@mdi/svg": "6.5.95", diff --git a/src/managers/notification-manager.ts b/src/managers/notification-manager.ts index 7eb9b410cd..db71b05f32 100644 --- a/src/managers/notification-manager.ts +++ b/src/managers/notification-manager.ts @@ -92,6 +92,10 @@ class NotificationManager extends LitElement { customElements.define("notification-manager", NotificationManager); declare global { + interface HTMLElementTagNameMap { + "notification-manager": NotificationManager; + } + // for fire event interface HASSDomEvents { "hass-notification": ShowToastParams; diff --git a/yarn.lock b/yarn.lock index cf8e942bd8..285de20715 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2126,6 +2126,26 @@ __metadata: languageName: node linkType: hard +"@material/drawer@npm:=14.0.0-canary.261f2db59.0": + version: 14.0.0-canary.261f2db59.0 + resolution: "@material/drawer@npm:14.0.0-canary.261f2db59.0" + dependencies: + "@material/animation": 14.0.0-canary.261f2db59.0 + "@material/base": 14.0.0-canary.261f2db59.0 + "@material/dom": 14.0.0-canary.261f2db59.0 + "@material/elevation": 14.0.0-canary.261f2db59.0 + "@material/feature-targeting": 14.0.0-canary.261f2db59.0 + "@material/list": 14.0.0-canary.261f2db59.0 + "@material/ripple": 14.0.0-canary.261f2db59.0 + "@material/rtl": 14.0.0-canary.261f2db59.0 + "@material/shape": 14.0.0-canary.261f2db59.0 + "@material/theme": 14.0.0-canary.261f2db59.0 + "@material/typography": 14.0.0-canary.261f2db59.0 + tslib: ^2.1.0 + checksum: 92146c61e00220f7aab80e3631c752e11147bee22e4a09e7bac21d233ae0aeff9545efe4d4a0fb10e889161ba06433ce9222bdcfda73de3ea54027cdadb3571a + languageName: node + linkType: hard + "@material/elevation@npm:14.0.0-canary.261f2db59.0": version: 14.0.0-canary.261f2db59.0 resolution: "@material/elevation@npm:14.0.0-canary.261f2db59.0" @@ -2343,6 +2363,20 @@ __metadata: languageName: node linkType: hard +"@material/mwc-drawer@npm:^0.25.3": + version: 0.25.3 + resolution: "@material/mwc-drawer@npm:0.25.3" + dependencies: + "@material/drawer": =14.0.0-canary.261f2db59.0 + "@material/mwc-base": ^0.25.3 + blocking-elements: ^0.1.0 + lit: ^2.0.0 + tslib: ^2.0.1 + wicg-inert: ^3.0.0 + checksum: 1195301cd943c1f7dae92ef33c383f5a2c3238d26fa44dd006d3c90d1c101cf17a5e67e491ef6ec49889a5cef682ea2f410397ac76be556cde1c8cb79f06874d + languageName: node + linkType: hard + "@material/mwc-fab@npm:0.25.3": version: 0.25.3 resolution: "@material/mwc-fab@npm:0.25.3" @@ -2624,6 +2658,30 @@ __metadata: languageName: node linkType: hard +"@material/mwc-top-app-bar-fixed@npm:^0.25.3": + version: 0.25.3 + resolution: "@material/mwc-top-app-bar-fixed@npm:0.25.3" + dependencies: + "@material/mwc-top-app-bar": ^0.25.3 + "@material/top-app-bar": =14.0.0-canary.261f2db59.0 + lit: ^2.0.0 + tslib: ^2.0.1 + checksum: f142b0625b0b5bd9335b43db977a20502da49707415c69bb8df8ba3626f81cc4c8283aeeece6f20d3a401f370b33ac88a41ebdcaa04fe90d5b2067142b1c460c + languageName: node + linkType: hard + +"@material/mwc-top-app-bar@npm:^0.25.3": + version: 0.25.3 + resolution: "@material/mwc-top-app-bar@npm:0.25.3" + dependencies: + "@material/mwc-base": ^0.25.3 + "@material/top-app-bar": =14.0.0-canary.261f2db59.0 + lit: ^2.0.0 + tslib: ^2.0.1 + checksum: c71ad8f557232827bab4b0cdf69fc3aa8caa9aa84193a9b085d3504c7d5c7a8d1e17aab7ebcf84cd0983e2ada8c88cc28de3f1d3a824c0b4fb9ce2ba96b48912 + languageName: node + linkType: hard + "@material/notched-outline@npm:14.0.0-canary.261f2db59.0, @material/notched-outline@npm:=14.0.0-canary.261f2db59.0": version: 14.0.0-canary.261f2db59.0 resolution: "@material/notched-outline@npm:14.0.0-canary.261f2db59.0" @@ -2869,7 +2927,7 @@ __metadata: languageName: node linkType: hard -"@material/top-app-bar@npm:14.0.0-canary.261f2db59.0": +"@material/top-app-bar@npm:14.0.0-canary.261f2db59.0, @material/top-app-bar@npm:=14.0.0-canary.261f2db59.0": version: 14.0.0-canary.261f2db59.0 resolution: "@material/top-app-bar@npm:14.0.0-canary.261f2db59.0" dependencies: @@ -9022,6 +9080,7 @@ fsevents@^1.2.7: "@material/mwc-checkbox": 0.25.3 "@material/mwc-circular-progress": 0.25.3 "@material/mwc-dialog": 0.25.3 + "@material/mwc-drawer": ^0.25.3 "@material/mwc-fab": 0.25.3 "@material/mwc-formfield": 0.25.3 "@material/mwc-icon-button": "patch:@material/mwc-icon-button@0.25.3#./.yarn/patches/@material/mwc-icon-button/remove-icon.patch" @@ -9036,6 +9095,7 @@ fsevents@^1.2.7: "@material/mwc-tab": 0.25.3 "@material/mwc-tab-bar": 0.25.3 "@material/mwc-textfield": 0.25.3 + "@material/mwc-top-app-bar-fixed": ^0.25.3 "@material/top-app-bar": 14.0.0-canary.261f2db59.0 "@mdi/js": 6.5.95 "@mdi/svg": 6.5.95 From a67799a670d3f1220400f7ad8acbeb168edddc2d Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 5 Jan 2022 14:08:21 -0800 Subject: [PATCH 004/127] Allow markdown readme above the gallery pages (#11103) --- build-scripts/gulp/gallery.js | 38 ++++++++++++++++++++---- gallery/src/demos/demo-ha-alert.markdown | 14 +++++++++ gallery/src/ha-gallery.ts | 26 ++++++++++++++-- 3 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 gallery/src/demos/demo-ha-alert.markdown diff --git a/build-scripts/gulp/gallery.js b/build-scripts/gulp/gallery.js index 9522d48b5c..16848ec723 100644 --- a/build-scripts/gulp/gallery.js +++ b/build-scripts/gulp/gallery.js @@ -2,6 +2,7 @@ const gulp = require("gulp"); const fs = require("fs"); const path = require("path"); +const marked = require("marked"); const env = require("../env"); const paths = require("../paths"); @@ -20,19 +21,46 @@ gulp.task("gather-gallery-demos", async function gatherDemos() { path.resolve(paths.gallery_dir, "src/demos") ); + const galleryBuild = path.resolve(paths.gallery_dir, "build"); + fs.mkdirSync(galleryBuild, { recursive: true }); + let content = "export const DEMOS = {\n"; for (const file of files) { + if (!file.endsWith(".ts")) { + continue; + } const demoId = path.basename(file, ".ts"); - const demoPath = "../src/demos/" + demoId; - content += ` "${demoId.substring(5)}": () => import("${demoPath}"),\n`; + const descriptionFile = path.resolve( + paths.gallery_dir, + "src/demos", + `${demoId}.markdown` + ); + const hasDescription = fs.existsSync(descriptionFile); + if (hasDescription) { + const descriptionContent = fs.readFileSync(descriptionFile, "utf-8"); + fs.writeFileSync( + path.resolve(galleryBuild, `${demoId}-description.ts`), + ` + import {html} from "lit"; + export default html\`${marked(descriptionContent)}\` + ` + ); + } + const demoPath = `../src/demos/${demoId}`; + const descriptionPath = `./${demoId}-description`; + content += ` "${demoId.substring(5)}": { + ${ + hasDescription + ? `description: () => import("${descriptionPath}").then(m => m.default),` + : "" + } + load: () => import("${demoPath}") + },\n`; } content += "};"; - const galleryBuild = path.resolve(paths.gallery_dir, "build"); - - fs.mkdirSync(galleryBuild, { recursive: true }); fs.writeFileSync( path.resolve(galleryBuild, "import-demos.ts"), content, diff --git a/gallery/src/demos/demo-ha-alert.markdown b/gallery/src/demos/demo-ha-alert.markdown new file mode 100644 index 0000000000..0f5a01d43b --- /dev/null +++ b/gallery/src/demos/demo-ha-alert.markdown @@ -0,0 +1,14 @@ +The `` element is used to display a message to the user that requires attention. + +The `header` option should not be used without a description. + + +Usage: + +```html +Look, an alert! +``` + +This will show: + +Look, an alert! diff --git a/gallery/src/ha-gallery.ts b/gallery/src/ha-gallery.ts index d7d38b2381..4f044096cb 100644 --- a/gallery/src/ha-gallery.ts +++ b/gallery/src/ha-gallery.ts @@ -3,6 +3,7 @@ import "@material/mwc-drawer"; import "@material/mwc-top-app-bar-fixed"; import { html, css, LitElement, PropertyValues } from "lit"; import { customElement, property, query } from "lit/decorators"; +import { until } from "lit/directives/until"; import "../../src/components/ha-icon-button"; import "../../src/managers/notification-manager"; import { haStyle } from "../../src/resources/styles"; @@ -99,7 +100,23 @@ class HaGallery extends LitElement {
${this._demo}
-
${dynamicElement(`demo-${this._demo}`)}
+
+ ${DEMOS[this._demo].description + ? html` + ${until( + DEMOS[this._demo].description().then( + (content) => html` + +
${content}
+
+ ` + ), + "" + )} + ` + : ""} + ${dynamicElement(`demo-${this._demo}`)} +
Date: Thu, 6 Jan 2022 01:21:17 -0800 Subject: [PATCH 005/127] Gallery: Make sidebar collapsible + more tweaks (#11104) --- build-scripts/gulp/gallery.js | 43 ++++-- gallery/src/demos/demo-introduction.markdown | 8 ++ gallery/src/demos/demo-introduction.ts | 43 ------ gallery/src/ha-gallery.ts | 132 ++++++++----------- gallery/src/sidebar.ts | 69 ++++++++++ 5 files changed, 165 insertions(+), 130 deletions(-) create mode 100644 gallery/src/demos/demo-introduction.markdown delete mode 100644 gallery/src/demos/demo-introduction.ts create mode 100644 gallery/src/sidebar.ts diff --git a/build-scripts/gulp/gallery.js b/build-scripts/gulp/gallery.js index 16848ec723..6e45f045cb 100644 --- a/build-scripts/gulp/gallery.js +++ b/build-scripts/gulp/gallery.js @@ -17,25 +17,33 @@ require("./entry-html.js"); require("./rollup.js"); gulp.task("gather-gallery-demos", async function gatherDemos() { - const files = await fs.promises.readdir( - path.resolve(paths.gallery_dir, "src/demos") - ); + const demoDir = path.resolve(paths.gallery_dir, "src/demos"); + const files = await fs.promises.readdir(demoDir); const galleryBuild = path.resolve(paths.gallery_dir, "build"); fs.mkdirSync(galleryBuild, { recursive: true }); let content = "export const DEMOS = {\n"; + const processed = new Set(); + for (const file of files) { - if (!file.endsWith(".ts")) { + let demoId = path.basename( + file, + file.endsWith(".ts") ? ".ts" : ".markdown" + ); + + // Can be processed if we saw demo or description before. + if (processed.has(demoId)) { continue; } - const demoId = path.basename(file, ".ts"); - const descriptionFile = path.resolve( - paths.gallery_dir, - "src/demos", - `${demoId}.markdown` - ); + + processed.add(demoId); + + const demoFile = path.resolve(demoDir, `${demoId}.ts`); + + const descriptionFile = path.resolve(demoDir, `${demoId}.markdown`); + const hasDemo = fs.existsSync(demoFile); const hasDescription = fs.existsSync(descriptionFile); if (hasDescription) { const descriptionContent = fs.readFileSync(descriptionFile, "utf-8"); @@ -55,7 +63,8 @@ gulp.task("gather-gallery-demos", async function gatherDemos() { ? `description: () => import("${descriptionPath}").then(m => m.default),` : "" } - load: () => import("${demoPath}") + ${hasDemo ? `load: () => import("${demoPath}")` : ""} + },\n`; } @@ -84,7 +93,17 @@ gulp.task( ), "copy-static-gallery", "gen-index-gallery-dev", - env.useRollup() ? "rollup-dev-server-gallery" : "webpack-dev-server-gallery" + gulp.parallel( + env.useRollup() + ? "rollup-dev-server-gallery" + : "webpack-dev-server-gallery", + async function watchMarkdownFiles() { + gulp.watch( + path.resolve(paths.gallery_dir, "src/demos/*.markdown"), + gulp.series("gather-gallery-demos") + ); + } + ) ) ); diff --git a/gallery/src/demos/demo-introduction.markdown b/gallery/src/demos/demo-introduction.markdown new file mode 100644 index 0000000000..d80033b05e --- /dev/null +++ b/gallery/src/demos/demo-introduction.markdown @@ -0,0 +1,8 @@ +Lovelace has many different cards. Each card allows the user to tell +a different story about what is going on in their house. These cards +are very customizable, as no household is the same. + +This gallery helps our developers and designers to see all the +different states that each card can be in. + +Check [the Lovelace documentation](https://www.home-assistant.io/lovelace) for instructions on how to get started with Lovelace. diff --git a/gallery/src/demos/demo-introduction.ts b/gallery/src/demos/demo-introduction.ts deleted file mode 100644 index 29e306bbff..0000000000 --- a/gallery/src/demos/demo-introduction.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { css, html, LitElement, TemplateResult } from "lit"; -import { customElement } from "lit/decorators"; -import "../../../src/components/ha-card"; -import "../../../src/components/ha-markdown"; - -@customElement("demo-introduction") -export class DemoIntroduction extends LitElement { - protected render(): TemplateResult { - return html` - -
- -
-
- `; - } - - static get styles() { - return css` - ha-card { - max-width: 600px; - margin: 24px auto; - } - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - "demo-introduction": DemoIntroduction; - } -} diff --git a/gallery/src/ha-gallery.ts b/gallery/src/ha-gallery.ts index 4f044096cb..2aa583ca12 100644 --- a/gallery/src/ha-gallery.ts +++ b/gallery/src/ha-gallery.ts @@ -4,55 +4,13 @@ import "@material/mwc-top-app-bar-fixed"; import { html, css, LitElement, PropertyValues } from "lit"; import { customElement, property, query } from "lit/decorators"; import { until } from "lit/directives/until"; +import "../../src/components/ha-card"; import "../../src/components/ha-icon-button"; import "../../src/managers/notification-manager"; import { haStyle } from "../../src/resources/styles"; -// eslint-disable-next-line import/extensions import { DEMOS } from "../build/import-demos"; import { dynamicElement } from "../../src/common/dom/dynamic-element-directive"; - -const DEMOS_GROUPED: { - header?: string; - demos?: string[]; - demoStart?: string; -}[] = [ - { - demos: ["introduction"], - }, - { - header: "Lovelace", - demoStart: "hui-", - }, - { - header: "Automation", - demoStart: "automation-", - }, - { - header: "Rest", - demoStart: "", - }, -]; - -const demosToProcess = new Set(Object.keys(DEMOS)); - -for (const group of Object.values(DEMOS_GROUPED)) { - if (group.demos) { - for (const demo of group.demos) { - demosToProcess.delete(demo); - } - } - if (!group.demos) { - group.demos = []; - } - if (group.demoStart !== undefined) { - for (const demo of demosToProcess) { - if (demo.startsWith(group.demoStart)) { - group.demos.push(demo); - demosToProcess.delete(demo); - } - } - } -} +import { SIDEBAR } from "./sidebar"; const FAKE_HASS = { // Just enough for computeRTL for notification-manager @@ -65,7 +23,7 @@ const FAKE_HASS = { @customElement("ha-gallery") class HaGallery extends LitElement { @property() private _demo = - document.location.hash.substring(1) || DEMOS_GROUPED[0].demos![0]; + document.location.hash.substring(1) || SIDEBAR[0].demos![0]; @query("notification-manager") private _notifications!: HTMLElementTagNameMap["notification-manager"]; @@ -73,23 +31,51 @@ class HaGallery extends LitElement { @query("mwc-drawer") private _drawer!: HTMLElementTagNameMap["mwc-drawer"]; + private _narrow = window.matchMedia("(max-width: 600px)").matches; + render() { + const sidebar: unknown[] = []; + + for (const group of SIDEBAR) { + let sectionOpen = false; + const links: unknown[] = []; + + for (const demo of group.demos!) { + const active = this._demo === demo; + if (active) { + sectionOpen = true; + } + + links.push(html` + ${group.demoStart === undefined + ? demo + : demo.substring(group.demoStart.length)} + `); + } + + sidebar.push( + group.header + ? html` +
+ ${group.header} + ${links} +
+ ` + : links + ); + } + return html` - + Home Assistant Design - +
html` - +
${content}
` @@ -126,21 +112,12 @@ class HaGallery extends LitElement { `; } - private _renderDemo(demo: string, demoStart?: string) { - return html` - ${demoStart === undefined ? demo : demo.substring(demoStart.length)} - `; - } - firstUpdated(changedProps: PropertyValues) { super.firstUpdated(changedProps); this.addEventListener("show-notification", (ev) => this._notifications.showDialog({ message: ev.detail.message }) ); - this.addEventListener("alert-dismissed-clicked", () => this._notifications.showDialog({ message: "Alert dismissed clicked" }) ); @@ -156,12 +133,15 @@ class HaGallery extends LitElement { window.addEventListener("hashchange", () => { this._demo = document.location.hash.substring(1); + if (this._narrow) { + this._drawer.open = false; + } }); } updated(changedProps: PropertyValues) { super.updated(changedProps); - if (changedProps.has("_demo") && this._demo) { + if (changedProps.has("_demo") && DEMOS[this._demo].load) { DEMOS[this._demo].load(); } } @@ -179,16 +159,18 @@ class HaGallery extends LitElement { -moz-user-select: initial; } - .section { - font-weight: bold; - } - .sidebar { padding: 4px; } - .sidebar p { - margin: 1em 12px; + .sidebar details { + margin-top: 1em; + } + + .sidebar summary { + cursor: pointer; + font-weight: bold; + margin-bottom: 8px; } .sidebar a { diff --git a/gallery/src/sidebar.ts b/gallery/src/sidebar.ts new file mode 100644 index 0000000000..71222f59a0 --- /dev/null +++ b/gallery/src/sidebar.ts @@ -0,0 +1,69 @@ +import { DEMOS } from "../build/import-demos"; + +export const SIDEBAR: SidebarSection[] = [ + { + demos: ["introduction"], + }, + + { + // Each section has a header + header: "Lovelace", + // Specify demos to make sure they are put on top. + demos: [], + // Add a demoStart to automatically gather demos based on their name + demoStart: "hui-", + }, + { + header: "Automation", + demoStart: "automation-", + }, + { + header: "Components", + demos: [ + "ha-alert", + "ha-bar", + "ha-chips", + "ha-faded", + "ha-form", + "ha-label-badge", + "ha-selector", + ], + }, + { + header: "More Info", + demoStart: "more-info-", + }, + { + header: "Rest", + demoStart: "", // empty string matches all. + }, +]; + +interface SidebarSection { + header?: string; + demos?: string[]; + demoStart?: string; +} + +const demosToProcess = new Set(Object.keys(DEMOS)); + +for (const group of Object.values(SIDEBAR)) { + // Any pre-defined groups will not be sorted. + if (group.demos) { + for (const demo of group.demos) { + demosToProcess.delete(demo); + } + } else { + group.demos = []; + } +} +for (const group of Object.values(SIDEBAR)) { + if (group.demoStart !== undefined) { + for (const demo of demosToProcess) { + if (demo.startsWith(group.demoStart)) { + group.demos!.push(demo); + demosToProcess.delete(demo); + } + } + } +} From fb9ea981edb38324eb8d69253214dfe7f0ab01a6 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Thu, 6 Jan 2022 14:52:08 +0100 Subject: [PATCH 006/127] Ignore button in scenes (#11109) --- src/data/scene.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/data/scene.ts b/src/data/scene.ts index 568db76998..f97cc2fa59 100644 --- a/src/data/scene.ts +++ b/src/data/scene.ts @@ -6,13 +6,15 @@ import { navigate } from "../common/navigate"; import { HomeAssistant, ServiceCallResponse } from "../types"; export const SCENE_IGNORED_DOMAINS = [ - "sensor", "binary_sensor", - "device_tracker", - "person", - "persistent_notification", + "button", "configuration", + "device_tracker", "image_processing", + "input_button", + "persistent_notification", + "person", + "sensor", "sun", "weather", "zone", From 2c0d330f1f4259e86f1bb2c3057eeb2ae0ea7b55 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 6 Jan 2022 20:20:57 -0800 Subject: [PATCH 007/127] Reorganize gallery (#11116) * Reorganize gallery * GitHub edit links * Render sidebar during build * Auto rebuild when sidebar changes * Yarn dedupe * Fixes * Allow just metadata without text * Show edit text link if metadata defined * Update build-scripts/gulp/gallery.js Co-authored-by: Zack Barett Co-authored-by: Zack Barett --- build-scripts/gulp/clean.js | 2 +- build-scripts/gulp/gallery.js | 117 ++++++++++++++---- build-scripts/paths.js | 1 + gallery/sidebar.js | 40 ++++++ gallery/src/components/demo-description.ts | 44 +++++++ .../describe-action.ts} | 8 +- .../describe-condition.ts} | 4 +- .../describe-trigger.ts} | 4 +- .../editor-action.ts} | 38 +++--- .../editor-condition.ts} | 36 +++--- .../editor-trigger.ts} | 46 +++---- .../trace-timeline.ts} | 14 +-- .../trace.ts} | 16 +-- .../ha-alert.markdown} | 0 .../ha-alert.ts} | 12 +- .../{demo-ha-bar.ts => components/ha-bar.ts} | 8 +- .../ha-chips.ts} | 12 +- .../ha-faded.ts} | 10 +- .../ha-form.ts} | 12 +- .../ha-label-badge.ts} | 8 +- .../ha-selector.ts} | 24 ++-- .../introduction.markdown} | 3 + .../demos/lovelace/alarm-panel-card.markdown | 3 + .../alarm-panel-card.ts} | 10 +- .../area-card.ts} | 10 +- .../conditional-card.ts} | 10 +- .../entities-card.ts} | 10 +- .../entity-button-card.ts} | 10 +- .../entity-filter-card.ts} | 10 +- .../gauge-card.ts} | 10 +- .../glance-card.ts} | 10 +- .../grid-and-stack-card.ts} | 12 +- .../iframe-card.ts} | 8 +- .../light-card.ts} | 10 +- .../map-card.ts} | 10 +- .../markdown-card.ts} | 10 +- .../media-control-card.ts} | 10 +- .../media-player-row.ts} | 10 +- .../picture-elements-card.ts} | 10 +- .../picture-entity-card.ts} | 10 +- .../picture-glance-card.ts} | 10 +- .../plant-card.ts} | 10 +- .../shopping-list-card.ts} | 8 +- .../thermostat-card.ts} | 10 +- .../cover.ts} | 12 +- .../light.ts} | 12 +- .../integration-card.ts} | 26 ++-- .../util-long-press.ts} | 8 +- gallery/src/ha-gallery.ts | 90 ++++++++------ gallery/src/sidebar.ts | 69 ----------- package.json | 2 + yarn.lock | 26 ++-- 52 files changed, 511 insertions(+), 404 deletions(-) create mode 100644 gallery/sidebar.js create mode 100644 gallery/src/components/demo-description.ts rename gallery/src/demos/{demo-automation-describe-action.ts => automation/describe-action.ts} (89%) rename gallery/src/demos/{demo-automation-describe-condition.ts => automation/describe-condition.ts} (92%) rename gallery/src/demos/{demo-automation-describe-trigger.ts => automation/describe-trigger.ts} (92%) rename gallery/src/demos/{demo-automation-editor-action.ts => automation/editor-action.ts} (57%) rename gallery/src/demos/{demo-automation-editor-condition.ts => automation/editor-condition.ts} (62%) rename gallery/src/demos/{demo-automation-editor-trigger.ts => automation/editor-trigger.ts} (58%) rename gallery/src/demos/{demo-automation-trace-timeline.ts => automation/trace-timeline.ts} (83%) rename gallery/src/demos/{demo-automation-trace.ts => automation/trace.ts} (82%) rename gallery/src/demos/{demo-ha-alert.markdown => components/ha-alert.markdown} (100%) rename gallery/src/demos/{demo-ha-alert.ts => components/ha-alert.ts} (94%) rename gallery/src/demos/{demo-ha-bar.ts => components/ha-bar.ts} (90%) rename gallery/src/demos/{demo-ha-chips.ts => components/ha-chips.ts} (86%) rename gallery/src/demos/{demo-ha-faded.ts => components/ha-faded.ts} (96%) rename gallery/src/demos/{demo-ha-form.ts => components/ha-form.ts} (94%) rename gallery/src/demos/{demo-ha-label-badge.ts => components/ha-label-badge.ts} (92%) rename gallery/src/demos/{demo-ha-selector.ts => components/ha-selector.ts} (81%) rename gallery/src/demos/{demo-introduction.markdown => introduction/introduction.markdown} (93%) create mode 100644 gallery/src/demos/lovelace/alarm-panel-card.markdown rename gallery/src/demos/{demo-hui-alarm-panel-card.ts => lovelace/alarm-panel-card.ts} (87%) rename gallery/src/demos/{demo-hui-area-card.ts => lovelace/area-card.ts} (93%) rename gallery/src/demos/{demo-hui-conditional-card.ts => lovelace/conditional-card.ts} (85%) rename gallery/src/demos/{demo-hui-entities-card.ts => lovelace/entities-card.ts} (95%) rename gallery/src/demos/{demo-hui-entity-button-card.ts => lovelace/entity-button-card.ts} (85%) rename gallery/src/demos/{demo-hui-entity-filter-card.ts => lovelace/entity-filter-card.ts} (91%) rename gallery/src/demos/{demo-hui-gauge-card.ts => lovelace/gauge-card.ts} (90%) rename gallery/src/demos/{demo-hui-glance-card.ts => lovelace/glance-card.ts} (95%) rename gallery/src/demos/{demo-hui-grid-and-stack-card.ts => lovelace/grid-and-stack-card.ts} (93%) rename gallery/src/demos/{demo-hui-iframe-card.ts => lovelace/iframe-card.ts} (84%) rename gallery/src/demos/{demo-hui-light-card.ts => lovelace/light-card.ts} (86%) rename gallery/src/demos/{demo-hui-map-card.ts => lovelace/map-card.ts} (93%) rename gallery/src/demos/{demo-hui-markdown-card.ts => lovelace/markdown-card.ts} (95%) rename gallery/src/demos/{demo-hui-media-control-card.ts => lovelace/media-control-card.ts} (92%) rename gallery/src/demos/{demo-hui-media-player-row.ts => lovelace/media-player-row.ts} (88%) rename gallery/src/demos/{demo-hui-picture-elements-card.ts => lovelace/picture-elements-card.ts} (92%) rename gallery/src/demos/{demo-hui-picture-entity-card.ts => lovelace/picture-entity-card.ts} (87%) rename gallery/src/demos/{demo-hui-picture-glance-card.ts => lovelace/picture-glance-card.ts} (91%) rename gallery/src/demos/{demo-hui-plant-card.ts => lovelace/plant-card.ts} (81%) rename gallery/src/demos/{demo-hui-shopping-list-card.ts => lovelace/shopping-list-card.ts} (83%) rename gallery/src/demos/{demo-hui-thermostat-card.ts => lovelace/thermostat-card.ts} (88%) rename gallery/src/demos/{demo-more-info-cover.ts => more-info/cover.ts} (93%) rename gallery/src/demos/{demo-more-info-light.ts => more-info/light.ts} (93%) rename gallery/src/demos/{demo-integration-card.ts => rest/integration-card.ts} (91%) rename gallery/src/demos/{demo-util-long-press.ts => rest/util-long-press.ts} (83%) delete mode 100644 gallery/src/sidebar.ts diff --git a/build-scripts/gulp/clean.js b/build-scripts/gulp/clean.js index 2b184d5e63..7bc0ed9e83 100644 --- a/build-scripts/gulp/clean.js +++ b/build-scripts/gulp/clean.js @@ -31,6 +31,6 @@ gulp.task("clean-hassio", () => gulp.task( "clean-gallery", gulp.parallel("clean-translations", () => - del([paths.gallery_output_root, paths.build_dir]) + del([paths.gallery_output_root, paths.gallery_build, paths.build_dir]) ) ); diff --git a/build-scripts/gulp/gallery.js b/build-scripts/gulp/gallery.js index 6e45f045cb..09ea380d7a 100644 --- a/build-scripts/gulp/gallery.js +++ b/build-scripts/gulp/gallery.js @@ -1,8 +1,11 @@ +/* eslint-disable */ // Run demo develop mode const gulp = require("gulp"); const fs = require("fs"); const path = require("path"); const marked = require("marked"); +const glob = require("glob"); +const yaml = require("js-yaml"); const env = require("../env"); const paths = require("../paths"); @@ -18,7 +21,7 @@ require("./rollup.js"); gulp.task("gather-gallery-demos", async function gatherDemos() { const demoDir = path.resolve(paths.gallery_dir, "src/demos"); - const files = await fs.promises.readdir(demoDir); + const files = glob.sync(path.resolve(demoDir, "**/*")); const galleryBuild = path.resolve(paths.gallery_dir, "build"); fs.mkdirSync(galleryBuild, { recursive: true }); @@ -28,47 +31,110 @@ gulp.task("gather-gallery-demos", async function gatherDemos() { const processed = new Set(); for (const file of files) { - let demoId = path.basename( - file, - file.endsWith(".ts") ? ".ts" : ".markdown" - ); + if (fs.lstatSync(file).isDirectory()) { + continue; + } + demoId = file.substring(demoDir.length + 1, file.lastIndexOf(".")); - // Can be processed if we saw demo or description before. if (processed.has(demoId)) { continue; } - processed.add(demoId); - const demoFile = path.resolve(demoDir, `${demoId}.ts`); + const [category, name] = demoId.split("/", 2); + const demoFile = path.resolve(demoDir, `${demoId}.ts`); const descriptionFile = path.resolve(demoDir, `${demoId}.markdown`); const hasDemo = fs.existsSync(demoFile); - const hasDescription = fs.existsSync(descriptionFile); + let hasDescription = fs.existsSync(descriptionFile); + let metadata = {}; if (hasDescription) { - const descriptionContent = fs.readFileSync(descriptionFile, "utf-8"); - fs.writeFileSync( - path.resolve(galleryBuild, `${demoId}-description.ts`), - ` - import {html} from "lit"; - export default html\`${marked(descriptionContent)}\` - ` - ); + let descriptionContent = fs.readFileSync(descriptionFile, "utf-8"); + + if (descriptionContent.startsWith("---")) { + const metadataEnd = descriptionContent.indexOf("---", 3); + metadata = yaml.load(descriptionContent.substring(3, metadataEnd)); + descriptionContent = descriptionContent + .substring(metadataEnd + 3) + .trim(); + } + + // If description is just metadata + if (descriptionContent === "") { + hasDescription = false; + } else { + fs.mkdirSync(path.resolve(galleryBuild, category), { recursive: true }); + fs.writeFileSync( + path.resolve(galleryBuild, `${demoId}-description.ts`), + ` + import {html} from "lit"; + export default html\`${marked(descriptionContent)}\` + ` + ); + } } - const demoPath = `../src/demos/${demoId}`; - const descriptionPath = `./${demoId}-description`; - content += ` "${demoId.substring(5)}": { + content += ` "${demoId}": { + metadata: ${JSON.stringify(metadata)}, ${ hasDescription - ? `description: () => import("${descriptionPath}").then(m => m.default),` + ? `description: () => import("./${demoId}-description").then(m => m.default),` : "" } - ${hasDemo ? `load: () => import("${demoPath}")` : ""} + ${hasDemo ? `load: () => import("../src/demos/${demoId}")` : ""} },\n`; } - content += "};"; + content += "};\n"; + + // Generate sidebar + const sidebarPath = path.resolve(paths.gallery_dir, "sidebar.js"); + // To make watch work during development + delete require.cache[sidebarPath]; + const sidebar = require(sidebarPath); + + const demosToProcess = {}; + for (const key of processed) { + const [category, demo] = key.split("/", 2); + if (!(category in demosToProcess)) { + demosToProcess[category] = new Set(); + } + demosToProcess[category].add(demo); + } + + for (const group of Object.values(sidebar)) { + const toProcess = demosToProcess[group.category]; + delete demosToProcess[group.category]; + + if (!toProcess) { + console.error("Unknown category", group.category); + continue; + } + + // Any pre-defined groups will not be sorted. + if (group.demos) { + for (const demo of group.demos) { + if (!toProcess.delete(demo)) { + console.error("Found unreferenced demo", demo); + } + } + } else { + group.demos = []; + } + for (const demo of Array.from(toProcess).sort()) { + group.demos.push(demo); + } + } + + for (const [category, demos] of Object.entries(demosToProcess)) { + sidebar.push({ + category, + header: category, + demos: Array.from(demos), + }); + } + + content += `export const SIDEBAR = ${JSON.stringify(sidebar, null, 2)};\n`; fs.writeFileSync( path.resolve(galleryBuild, "import-demos.ts"), @@ -99,7 +165,10 @@ gulp.task( : "webpack-dev-server-gallery", async function watchMarkdownFiles() { gulp.watch( - path.resolve(paths.gallery_dir, "src/demos/*.markdown"), + [ + path.resolve(paths.gallery_dir, "src/demos/**/*.markdown"), + path.resolve(paths.gallery_dir, "sidebar.js"), + ], gulp.series("gather-gallery-demos") ); } diff --git a/build-scripts/paths.js b/build-scripts/paths.js index d89f5f582a..241c7669dd 100644 --- a/build-scripts/paths.js +++ b/build-scripts/paths.js @@ -26,6 +26,7 @@ module.exports = { cast_output_es5: path.resolve(__dirname, "../cast/dist/frontend_es5"), gallery_dir: path.resolve(__dirname, "../gallery"), + gallery_build: path.resolve(__dirname, "../gallery/build"), gallery_output_root: path.resolve(__dirname, "../gallery/dist"), gallery_output_latest: path.resolve( __dirname, diff --git a/gallery/sidebar.js b/gallery/sidebar.js new file mode 100644 index 0000000000..2d40478a88 --- /dev/null +++ b/gallery/sidebar.js @@ -0,0 +1,40 @@ +module.exports = [ + { + category: "introduction", + demos: ["introduction"], + }, + + { + category: "lovelace", + // Each section has a header + header: "Lovelace", + // Specify demos to make sure they are put on top. + demos: [], + // Add a demoStart to automatically gather demos based on their name + }, + { + category: "automation", + header: "Automation", + }, + { + category: "components", + header: "Components", + demos: [ + "ha-alert", + "ha-bar", + "ha-chips", + "ha-faded", + "ha-form", + "ha-label-badge", + "ha-selector", + ], + }, + { + category: "more-info", + header: "More Info", + }, + { + category: "rest", + header: "Rest", + }, +]; diff --git a/gallery/src/components/demo-description.ts b/gallery/src/components/demo-description.ts new file mode 100644 index 0000000000..41dc6fc4a0 --- /dev/null +++ b/gallery/src/components/demo-description.ts @@ -0,0 +1,44 @@ +import { html, css, LitElement } from "lit"; +import { customElement, property } from "lit/decorators"; +import { until } from "lit/directives/until"; +import { haStyle } from "../../../src/resources/styles"; +import { DEMOS } from "../../build/import-demos"; + +@customElement("demo-description") +class DemoDescription extends LitElement { + @property() public demo!: string; + + render() { + if (!DEMOS[this.demo].description) { + return ""; + } + return html` + ${until( + DEMOS[this.demo].description().then( + (content) => html` + +
${content}
+
+ ` + ), + "" + )} + `; + } + + static styles = [ + haStyle, + css` + ha-card { + max-width: 600px; + margin: 16px auto; + } + `, + ]; +} + +declare global { + interface HTMLElementTagNameMap { + "demo-description": DemoDescription; + } +} diff --git a/gallery/src/demos/demo-automation-describe-action.ts b/gallery/src/demos/automation/describe-action.ts similarity index 89% rename from gallery/src/demos/demo-automation-describe-action.ts rename to gallery/src/demos/automation/describe-action.ts index ea9b13fff5..55c3317acc 100644 --- a/gallery/src/demos/demo-automation-describe-action.ts +++ b/gallery/src/demos/automation/describe-action.ts @@ -1,10 +1,10 @@ import { dump } from "js-yaml"; import { html, css, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; -import "../../../src/components/ha-card"; -import { describeAction } from "../../../src/data/script_i18n"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import { HomeAssistant } from "../../../src/types"; +import "../../../../src/components/ha-card"; +import { describeAction } from "../../../../src/data/script_i18n"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import { HomeAssistant } from "../../../../src/types"; const actions = [ { wait_template: "{{ true }}", alias: "Something with an alias" }, diff --git a/gallery/src/demos/demo-automation-describe-condition.ts b/gallery/src/demos/automation/describe-condition.ts similarity index 92% rename from gallery/src/demos/demo-automation-describe-condition.ts rename to gallery/src/demos/automation/describe-condition.ts index 60f42d78e2..11de8b9781 100644 --- a/gallery/src/demos/demo-automation-describe-condition.ts +++ b/gallery/src/demos/automation/describe-condition.ts @@ -1,8 +1,8 @@ import { dump } from "js-yaml"; import { html, css, LitElement, TemplateResult } from "lit"; import { customElement } from "lit/decorators"; -import "../../../src/components/ha-card"; -import { describeCondition } from "../../../src/data/automation_i18n"; +import "../../../../src/components/ha-card"; +import { describeCondition } from "../../../../src/data/automation_i18n"; const conditions = [ { condition: "and" }, diff --git a/gallery/src/demos/demo-automation-describe-trigger.ts b/gallery/src/demos/automation/describe-trigger.ts similarity index 92% rename from gallery/src/demos/demo-automation-describe-trigger.ts rename to gallery/src/demos/automation/describe-trigger.ts index 8a409386c0..6bfe3213c3 100644 --- a/gallery/src/demos/demo-automation-describe-trigger.ts +++ b/gallery/src/demos/automation/describe-trigger.ts @@ -1,8 +1,8 @@ import { dump } from "js-yaml"; import { html, css, LitElement, TemplateResult } from "lit"; import { customElement } from "lit/decorators"; -import "../../../src/components/ha-card"; -import { describeTrigger } from "../../../src/data/automation_i18n"; +import "../../../../src/components/ha-card"; +import { describeTrigger } from "../../../../src/data/automation_i18n"; const triggers = [ { platform: "state" }, diff --git a/gallery/src/demos/demo-automation-editor-action.ts b/gallery/src/demos/automation/editor-action.ts similarity index 57% rename from gallery/src/demos/demo-automation-editor-action.ts rename to gallery/src/demos/automation/editor-action.ts index 1aea950b92..01769ccaa8 100644 --- a/gallery/src/demos/demo-automation-editor-action.ts +++ b/gallery/src/demos/automation/editor-action.ts @@ -1,25 +1,25 @@ /* eslint-disable lit/no-template-arrow */ import { LitElement, TemplateResult, html } from "lit"; import { customElement, state } from "lit/decorators"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import type { HomeAssistant } from "../../../src/types"; -import "../components/demo-black-white-row"; -import { mockEntityRegistry } from "../../../demo/src/stubs/entity_registry"; -import { mockDeviceRegistry } from "../../../demo/src/stubs/device_registry"; -import { mockAreaRegistry } from "../../../demo/src/stubs/area_registry"; -import { mockHassioSupervisor } from "../../../demo/src/stubs/hassio_supervisor"; -import "../../../src/panels/config/automation/action/ha-automation-action"; -import { HaChooseAction } from "../../../src/panels/config/automation/action/types/ha-automation-action-choose"; -import { HaDelayAction } from "../../../src/panels/config/automation/action/types/ha-automation-action-delay"; -import { HaDeviceAction } from "../../../src/panels/config/automation/action/types/ha-automation-action-device_id"; -import { HaEventAction } from "../../../src/panels/config/automation/action/types/ha-automation-action-event"; -import { HaRepeatAction } from "../../../src/panels/config/automation/action/types/ha-automation-action-repeat"; -import { HaSceneAction } from "../../../src/panels/config/automation/action/types/ha-automation-action-scene"; -import { HaServiceAction } from "../../../src/panels/config/automation/action/types/ha-automation-action-service"; -import { HaWaitForTriggerAction } from "../../../src/panels/config/automation/action/types/ha-automation-action-wait_for_trigger"; -import { HaWaitAction } from "../../../src/panels/config/automation/action/types/ha-automation-action-wait_template"; -import { Action } from "../../../src/data/script"; -import { HaConditionAction } from "../../../src/panels/config/automation/action/types/ha-automation-action-condition"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import type { HomeAssistant } from "../../../../src/types"; +import "../../components/demo-black-white-row"; +import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry"; +import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry"; +import { mockAreaRegistry } from "../../../../demo/src/stubs/area_registry"; +import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor"; +import "../../../../src/panels/config/automation/action/ha-automation-action"; +import { HaChooseAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-choose"; +import { HaDelayAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-delay"; +import { HaDeviceAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-device_id"; +import { HaEventAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-event"; +import { HaRepeatAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-repeat"; +import { HaSceneAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-scene"; +import { HaServiceAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-service"; +import { HaWaitForTriggerAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-wait_for_trigger"; +import { HaWaitAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-wait_template"; +import { Action } from "../../../../src/data/script"; +import { HaConditionAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-condition"; const SCHEMAS: { name: string; actions: Action[] }[] = [ { name: "Event", actions: [HaEventAction.defaultConfig] }, diff --git a/gallery/src/demos/demo-automation-editor-condition.ts b/gallery/src/demos/automation/editor-condition.ts similarity index 62% rename from gallery/src/demos/demo-automation-editor-condition.ts rename to gallery/src/demos/automation/editor-condition.ts index 4b1ebd8a13..77e42e6171 100644 --- a/gallery/src/demos/demo-automation-editor-condition.ts +++ b/gallery/src/demos/automation/editor-condition.ts @@ -1,24 +1,24 @@ /* eslint-disable lit/no-template-arrow */ import { LitElement, TemplateResult, html } from "lit"; import { customElement, state } from "lit/decorators"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import type { HomeAssistant } from "../../../src/types"; -import "../components/demo-black-white-row"; -import { mockEntityRegistry } from "../../../demo/src/stubs/entity_registry"; -import { mockDeviceRegistry } from "../../../demo/src/stubs/device_registry"; -import { mockAreaRegistry } from "../../../demo/src/stubs/area_registry"; -import { mockHassioSupervisor } from "../../../demo/src/stubs/hassio_supervisor"; -import type { Condition } from "../../../src/data/automation"; -import "../../../src/panels/config/automation/condition/ha-automation-condition"; -import { HaDeviceCondition } from "../../../src/panels/config/automation/condition/types/ha-automation-condition-device"; -import { HaLogicalCondition } from "../../../src/panels/config/automation/condition/types/ha-automation-condition-logical"; -import HaNumericStateCondition from "../../../src/panels/config/automation/condition/types/ha-automation-condition-numeric_state"; -import { HaStateCondition } from "../../../src/panels/config/automation/condition/types/ha-automation-condition-state"; -import { HaSunCondition } from "../../../src/panels/config/automation/condition/types/ha-automation-condition-sun"; -import { HaTemplateCondition } from "../../../src/panels/config/automation/condition/types/ha-automation-condition-template"; -import { HaTimeCondition } from "../../../src/panels/config/automation/condition/types/ha-automation-condition-time"; -import { HaTriggerCondition } from "../../../src/panels/config/automation/condition/types/ha-automation-condition-trigger"; -import { HaZoneCondition } from "../../../src/panels/config/automation/condition/types/ha-automation-condition-zone"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import type { HomeAssistant } from "../../../../src/types"; +import "../../components/demo-black-white-row"; +import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry"; +import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry"; +import { mockAreaRegistry } from "../../../../demo/src/stubs/area_registry"; +import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor"; +import type { Condition } from "../../../../src/data/automation"; +import "../../../../src/panels/config/automation/condition/ha-automation-condition"; +import { HaDeviceCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-device"; +import { HaLogicalCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-logical"; +import HaNumericStateCondition from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-numeric_state"; +import { HaStateCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-state"; +import { HaSunCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-sun"; +import { HaTemplateCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-template"; +import { HaTimeCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-time"; +import { HaTriggerCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-trigger"; +import { HaZoneCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-zone"; const SCHEMAS: { name: string; conditions: Condition[] }[] = [ { diff --git a/gallery/src/demos/demo-automation-editor-trigger.ts b/gallery/src/demos/automation/editor-trigger.ts similarity index 58% rename from gallery/src/demos/demo-automation-editor-trigger.ts rename to gallery/src/demos/automation/editor-trigger.ts index 0bc04b7435..af6d3bd6bb 100644 --- a/gallery/src/demos/demo-automation-editor-trigger.ts +++ b/gallery/src/demos/automation/editor-trigger.ts @@ -1,29 +1,29 @@ /* eslint-disable lit/no-template-arrow */ import { LitElement, TemplateResult, html } from "lit"; import { customElement, state } from "lit/decorators"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import type { HomeAssistant } from "../../../src/types"; -import "../components/demo-black-white-row"; -import { mockEntityRegistry } from "../../../demo/src/stubs/entity_registry"; -import { mockDeviceRegistry } from "../../../demo/src/stubs/device_registry"; -import { mockAreaRegistry } from "../../../demo/src/stubs/area_registry"; -import { mockHassioSupervisor } from "../../../demo/src/stubs/hassio_supervisor"; -import type { Trigger } from "../../../src/data/automation"; -import { HaGeolocationTrigger } from "../../../src/panels/config/automation/trigger/types/ha-automation-trigger-geo_location"; -import { HaEventTrigger } from "../../../src/panels/config/automation/trigger/types/ha-automation-trigger-event"; -import { HaHassTrigger } from "../../../src/panels/config/automation/trigger/types/ha-automation-trigger-homeassistant"; -import { HaNumericStateTrigger } from "../../../src/panels/config/automation/trigger/types/ha-automation-trigger-numeric_state"; -import { HaSunTrigger } from "../../../src/panels/config/automation/trigger/types/ha-automation-trigger-sun"; -import { HaTagTrigger } from "../../../src/panels/config/automation/trigger/types/ha-automation-trigger-tag"; -import { HaTemplateTrigger } from "../../../src/panels/config/automation/trigger/types/ha-automation-trigger-template"; -import { HaTimeTrigger } from "../../../src/panels/config/automation/trigger/types/ha-automation-trigger-time"; -import { HaTimePatternTrigger } from "../../../src/panels/config/automation/trigger/types/ha-automation-trigger-time_pattern"; -import { HaWebhookTrigger } from "../../../src/panels/config/automation/trigger/types/ha-automation-trigger-webhook"; -import { HaZoneTrigger } from "../../../src/panels/config/automation/trigger/types/ha-automation-trigger-zone"; -import { HaDeviceTrigger } from "../../../src/panels/config/automation/trigger/types/ha-automation-trigger-device"; -import { HaStateTrigger } from "../../../src/panels/config/automation/trigger/types/ha-automation-trigger-state"; -import { HaMQTTTrigger } from "../../../src/panels/config/automation/trigger/types/ha-automation-trigger-mqtt"; -import "../../../src/panels/config/automation/trigger/ha-automation-trigger"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import type { HomeAssistant } from "../../../../src/types"; +import "../../components/demo-black-white-row"; +import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry"; +import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry"; +import { mockAreaRegistry } from "../../../../demo/src/stubs/area_registry"; +import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor"; +import type { Trigger } from "../../../../src/data/automation"; +import { HaGeolocationTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-geo_location"; +import { HaEventTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-event"; +import { HaHassTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-homeassistant"; +import { HaNumericStateTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-numeric_state"; +import { HaSunTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-sun"; +import { HaTagTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-tag"; +import { HaTemplateTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-template"; +import { HaTimeTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-time"; +import { HaTimePatternTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-time_pattern"; +import { HaWebhookTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-webhook"; +import { HaZoneTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-zone"; +import { HaDeviceTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-device"; +import { HaStateTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-state"; +import { HaMQTTTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-mqtt"; +import "../../../../src/panels/config/automation/trigger/ha-automation-trigger"; const SCHEMAS: { name: string; triggers: Trigger[] }[] = [ { diff --git a/gallery/src/demos/demo-automation-trace-timeline.ts b/gallery/src/demos/automation/trace-timeline.ts similarity index 83% rename from gallery/src/demos/demo-automation-trace-timeline.ts rename to gallery/src/demos/automation/trace-timeline.ts index f94cd97fb6..b4d9fea9ec 100644 --- a/gallery/src/demos/demo-automation-trace-timeline.ts +++ b/gallery/src/demos/automation/trace-timeline.ts @@ -1,13 +1,13 @@ /* eslint-disable lit/no-template-arrow */ import { html, css, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; -import "../../../src/components/ha-card"; -import "../../../src/components/trace/hat-script-graph"; -import "../../../src/components/trace/hat-trace-timeline"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import { HomeAssistant } from "../../../src/types"; -import { mockDemoTrace } from "../data/traces/mock-demo-trace"; -import { DemoTrace } from "../data/traces/types"; +import "../../../../src/components/ha-card"; +import "../../../../src/components/trace/hat-script-graph"; +import "../../../../src/components/trace/hat-trace-timeline"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import { HomeAssistant } from "../../../../src/types"; +import { mockDemoTrace } from "../../data/traces/mock-demo-trace"; +import { DemoTrace } from "../../data/traces/types"; const traces: DemoTrace[] = [ mockDemoTrace({ state: "running" }), diff --git a/gallery/src/demos/demo-automation-trace.ts b/gallery/src/demos/automation/trace.ts similarity index 82% rename from gallery/src/demos/demo-automation-trace.ts rename to gallery/src/demos/automation/trace.ts index 508576c22f..7de26e1004 100644 --- a/gallery/src/demos/demo-automation-trace.ts +++ b/gallery/src/demos/automation/trace.ts @@ -1,14 +1,14 @@ /* eslint-disable lit/no-template-arrow */ import { html, css, LitElement, TemplateResult } from "lit"; -import "../../../src/components/ha-card"; -import "../../../src/components/trace/hat-script-graph"; -import "../../../src/components/trace/hat-trace-timeline"; +import "../../../../src/components/ha-card"; +import "../../../../src/components/trace/hat-script-graph"; +import "../../../../src/components/trace/hat-trace-timeline"; import { customElement, property, state } from "lit/decorators"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import { HomeAssistant } from "../../../src/types"; -import { DemoTrace } from "../data/traces/types"; -import { basicTrace } from "../data/traces/basic_trace"; -import { motionLightTrace } from "../data/traces/motion-light-trace"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import { HomeAssistant } from "../../../../src/types"; +import { DemoTrace } from "../../data/traces/types"; +import { basicTrace } from "../../data/traces/basic_trace"; +import { motionLightTrace } from "../../data/traces/motion-light-trace"; const traces: DemoTrace[] = [basicTrace, motionLightTrace]; diff --git a/gallery/src/demos/demo-ha-alert.markdown b/gallery/src/demos/components/ha-alert.markdown similarity index 100% rename from gallery/src/demos/demo-ha-alert.markdown rename to gallery/src/demos/components/ha-alert.markdown diff --git a/gallery/src/demos/demo-ha-alert.ts b/gallery/src/demos/components/ha-alert.ts similarity index 94% rename from gallery/src/demos/demo-ha-alert.ts rename to gallery/src/demos/components/ha-alert.ts index 3a62c4a1d2..c4f44e80a9 100644 --- a/gallery/src/demos/demo-ha-alert.ts +++ b/gallery/src/demos/components/ha-alert.ts @@ -1,10 +1,10 @@ import "@material/mwc-button/mwc-button"; import { css, html, LitElement, TemplateResult } from "lit"; import { customElement } from "lit/decorators"; -import { applyThemesOnElement } from "../../../src/common/dom/apply_themes_on_element"; -import "../../../src/components/ha-alert"; -import "../../../src/components/ha-card"; -import "../../../src/components/ha-logo-svg"; +import { applyThemesOnElement } from "../../../../src/common/dom/apply_themes_on_element"; +import "../../../../src/components/ha-alert"; +import "../../../../src/components/ha-card"; +import "../../../../src/components/ha-logo-svg"; const alerts: { title?: string; @@ -128,7 +128,7 @@ const alerts: { }, ]; -@customElement("demo-ha-alert") +@customElement("demo-components-ha-alert") export class DemoHaAlert extends LitElement { protected render(): TemplateResult { return html` @@ -212,6 +212,6 @@ export class DemoHaAlert extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-ha-alert": DemoHaAlert; + "demo-components-ha-alert": DemoHaAlert; } } diff --git a/gallery/src/demos/demo-ha-bar.ts b/gallery/src/demos/components/ha-bar.ts similarity index 90% rename from gallery/src/demos/demo-ha-bar.ts rename to gallery/src/demos/components/ha-bar.ts index 83f47f5dd6..797e3ff306 100644 --- a/gallery/src/demos/demo-ha-bar.ts +++ b/gallery/src/demos/components/ha-bar.ts @@ -1,8 +1,8 @@ import { html, css, LitElement, TemplateResult } from "lit"; import { customElement } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; -import "../../../src/components/ha-bar"; -import "../../../src/components/ha-card"; +import "../../../../src/components/ha-bar"; +import "../../../../src/components/ha-card"; const bars: { min?: number; @@ -34,7 +34,7 @@ const bars: { }, ]; -@customElement("demo-ha-bar") +@customElement("demo-components-ha-bar") export class DemoHaBar extends LitElement { protected render(): TemplateResult { return html` @@ -80,6 +80,6 @@ export class DemoHaBar extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-ha-bar": DemoHaBar; + "demo-components-ha-bar": DemoHaBar; } } diff --git a/gallery/src/demos/demo-ha-chips.ts b/gallery/src/demos/components/ha-chips.ts similarity index 86% rename from gallery/src/demos/demo-ha-chips.ts rename to gallery/src/demos/components/ha-chips.ts index d1dcc2ae7d..a81606458a 100644 --- a/gallery/src/demos/demo-ha-chips.ts +++ b/gallery/src/demos/components/ha-chips.ts @@ -1,10 +1,10 @@ import { mdiHomeAssistant } from "@mdi/js"; import { css, html, LitElement, TemplateResult } from "lit"; import { customElement } from "lit/decorators"; -import "../../../src/components/ha-card"; -import "../../../src/components/ha-chip"; -import "../../../src/components/ha-chip-set"; -import "../../../src/components/ha-svg-icon"; +import "../../../../src/components/ha-card"; +import "../../../../src/components/ha-chip"; +import "../../../../src/components/ha-chip-set"; +import "../../../../src/components/ha-svg-icon"; const chips: { icon?: string; @@ -23,7 +23,7 @@ const chips: { }, ]; -@customElement("demo-ha-chips") +@customElement("demo-components-ha-chips") export class DemoHaChips extends LitElement { protected render(): TemplateResult { return html` @@ -81,6 +81,6 @@ export class DemoHaChips extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-ha-chips": DemoHaChips; + "demo-components-ha-chips": DemoHaChips; } } diff --git a/gallery/src/demos/demo-ha-faded.ts b/gallery/src/demos/components/ha-faded.ts similarity index 96% rename from gallery/src/demos/demo-ha-faded.ts rename to gallery/src/demos/components/ha-faded.ts index 65dcb4315d..1f962ef101 100644 --- a/gallery/src/demos/demo-ha-faded.ts +++ b/gallery/src/demos/components/ha-faded.ts @@ -1,8 +1,8 @@ import { css, html, LitElement, TemplateResult } from "lit"; import { customElement } from "lit/decorators"; -import "../../../src/components/ha-card"; -import "../../../src/components/ha-faded"; -import "../../../src/components/ha-markdown"; +import "../../../../src/components/ha-card"; +import "../../../../src/components/ha-faded"; +import "../../../../src/components/ha-markdown"; const LONG_TEXT = ` Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc laoreet velit ut elit volutpat, eget ultrices odio lacinia. In imperdiet malesuada est, nec sagittis metus ultricies quis. Sed nisl ex, convallis porttitor ante quis, hendrerit tristique justo. Mauris pharetra venenatis augue, eu maximus sem cursus in. Quisque sed consequat risus. Suspendisse facilisis ligula a odio consectetur condimentum. Curabitur vehicula elit nec augue mollis, et volutpat massa dictum. @@ -18,7 +18,7 @@ Quisque posuere, velit sed porttitor dapibus, neque augue fringilla felis, eu lu const SMALL_TEXT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."; -@customElement("demo-ha-faded") +@customElement("demo-components-ha-faded") export class DemoHaFaded extends LitElement { protected render(): TemplateResult { return html` @@ -83,6 +83,6 @@ export class DemoHaFaded extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-ha-faded": DemoHaFaded; + "demo-components-ha-faded": DemoHaFaded; } } diff --git a/gallery/src/demos/demo-ha-form.ts b/gallery/src/demos/components/ha-form.ts similarity index 94% rename from gallery/src/demos/demo-ha-form.ts rename to gallery/src/demos/components/ha-form.ts index 69933af074..324eb3a58d 100644 --- a/gallery/src/demos/demo-ha-form.ts +++ b/gallery/src/demos/components/ha-form.ts @@ -2,10 +2,10 @@ import "@material/mwc-button"; import { LitElement, TemplateResult, html } from "lit"; import { customElement } from "lit/decorators"; -import { computeInitialHaFormData } from "../../../src/components/ha-form/compute-initial-ha-form-data"; -import type { HaFormSchema } from "../../../src/components/ha-form/types"; -import "../../../src/components/ha-form/ha-form"; -import "../components/demo-black-white-row"; +import { computeInitialHaFormData } from "../../../../src/components/ha-form/compute-initial-ha-form-data"; +import type { HaFormSchema } from "../../../../src/components/ha-form/types"; +import "../../../../src/components/ha-form/ha-form"; +import "../../components/demo-black-white-row"; const SCHEMAS: { title: string; @@ -248,7 +248,7 @@ const SCHEMAS: { }, ]; -@customElement("demo-ha-form") +@customElement("demo-components-ha-form") class DemoHaForm extends LitElement { private data = SCHEMAS.map( ({ schema, data }) => data || computeInitialHaFormData(schema) @@ -301,6 +301,6 @@ class DemoHaForm extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-ha-form": DemoHaForm; + "demo-components-ha-form": DemoHaForm; } } diff --git a/gallery/src/demos/demo-ha-label-badge.ts b/gallery/src/demos/components/ha-label-badge.ts similarity index 92% rename from gallery/src/demos/demo-ha-label-badge.ts rename to gallery/src/demos/components/ha-label-badge.ts index 277c539040..7a164dc87e 100644 --- a/gallery/src/demos/demo-ha-label-badge.ts +++ b/gallery/src/demos/components/ha-label-badge.ts @@ -1,7 +1,7 @@ import { html, css, LitElement, TemplateResult } from "lit"; import { customElement } from "lit/decorators"; -import "../../../src/components/ha-label-badge"; -import "../../../src/components/ha-card"; +import "../../../../src/components/ha-label-badge"; +import "../../../../src/components/ha-card"; const colors = ["#03a9f4", "#ffa600", "#43a047"]; @@ -50,7 +50,7 @@ const badges: { }, ]; -@customElement("demo-ha-label-badge") +@customElement("demo-components-ha-label-badge") export class DemoHaLabelBadge extends LitElement { protected render(): TemplateResult { return html` @@ -117,6 +117,6 @@ export class DemoHaLabelBadge extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-ha-label-badge": DemoHaLabelBadge; + "demo-components-ha-label-badge": DemoHaLabelBadge; } } diff --git a/gallery/src/demos/demo-ha-selector.ts b/gallery/src/demos/components/ha-selector.ts similarity index 81% rename from gallery/src/demos/demo-ha-selector.ts rename to gallery/src/demos/components/ha-selector.ts index 919a2c2419..b25790a299 100644 --- a/gallery/src/demos/demo-ha-selector.ts +++ b/gallery/src/demos/components/ha-selector.ts @@ -2,16 +2,16 @@ import "@material/mwc-button"; import { LitElement, TemplateResult, css, html } from "lit"; import { customElement, state } from "lit/decorators"; -import "../../../src/components/ha-selector/ha-selector"; -import "../../../src/components/ha-settings-row"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import type { HomeAssistant } from "../../../src/types"; -import "../components/demo-black-white-row"; -import { BlueprintInput } from "../../../src/data/blueprint"; -import { mockEntityRegistry } from "../../../demo/src/stubs/entity_registry"; -import { mockDeviceRegistry } from "../../../demo/src/stubs/device_registry"; -import { mockAreaRegistry } from "../../../demo/src/stubs/area_registry"; -import { mockHassioSupervisor } from "../../../demo/src/stubs/hassio_supervisor"; +import "../../../../src/components/ha-selector/ha-selector"; +import "../../../../src/components/ha-settings-row"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import type { HomeAssistant } from "../../../../src/types"; +import "../../components/demo-black-white-row"; +import { BlueprintInput } from "../../../../src/data/blueprint"; +import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry"; +import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry"; +import { mockAreaRegistry } from "../../../../demo/src/stubs/area_registry"; +import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor"; const SCHEMAS: { name: string; @@ -62,7 +62,7 @@ const SCHEMAS: { }, ]; -@customElement("demo-ha-selector") +@customElement("demo-components-ha-selector") class DemoHaSelector extends LitElement { @state() private hass!: HomeAssistant; @@ -126,6 +126,6 @@ class DemoHaSelector extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-ha-selector": DemoHaSelector; + "demo-components-ha-selector": DemoHaSelector; } } diff --git a/gallery/src/demos/demo-introduction.markdown b/gallery/src/demos/introduction/introduction.markdown similarity index 93% rename from gallery/src/demos/demo-introduction.markdown rename to gallery/src/demos/introduction/introduction.markdown index d80033b05e..a6fa62a9a7 100644 --- a/gallery/src/demos/demo-introduction.markdown +++ b/gallery/src/demos/introduction/introduction.markdown @@ -1,3 +1,6 @@ +--- +title: Introduction +--- Lovelace has many different cards. Each card allows the user to tell a different story about what is going on in their house. These cards are very customizable, as no household is the same. diff --git a/gallery/src/demos/lovelace/alarm-panel-card.markdown b/gallery/src/demos/lovelace/alarm-panel-card.markdown new file mode 100644 index 0000000000..30b1662ad7 --- /dev/null +++ b/gallery/src/demos/lovelace/alarm-panel-card.markdown @@ -0,0 +1,3 @@ +--- +title: Alarm Panel Card +--- diff --git a/gallery/src/demos/demo-hui-alarm-panel-card.ts b/gallery/src/demos/lovelace/alarm-panel-card.ts similarity index 87% rename from gallery/src/demos/demo-hui-alarm-panel-card.ts rename to gallery/src/demos/lovelace/alarm-panel-card.ts index be9a5a22e2..b55b1ca5d1 100644 --- a/gallery/src/demos/demo-hui-alarm-panel-card.ts +++ b/gallery/src/demos/lovelace/alarm-panel-card.ts @@ -1,8 +1,8 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { getEntity } from "../../../src/fake_data/entity"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; +import { getEntity } from "../../../../src/fake_data/entity"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; const ENTITIES = [ getEntity("alarm_control_panel", "alarm", "disarmed", { @@ -70,7 +70,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-alarm-panel-card") +@customElement("demo-lovelace-alarm-panel-card") class DemoAlarmPanelEntity extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -89,6 +89,6 @@ class DemoAlarmPanelEntity extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-alarm-panel-card": DemoAlarmPanelEntity; + "demo-lovelace-alarm-panel-card": DemoAlarmPanelEntity; } } diff --git a/gallery/src/demos/demo-hui-area-card.ts b/gallery/src/demos/lovelace/area-card.ts similarity index 93% rename from gallery/src/demos/demo-hui-area-card.ts rename to gallery/src/demos/lovelace/area-card.ts index bbb6dedfd2..3d46fc031d 100644 --- a/gallery/src/demos/demo-hui-area-card.ts +++ b/gallery/src/demos/lovelace/area-card.ts @@ -1,8 +1,8 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { getEntity } from "../../../src/fake_data/entity"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; +import { getEntity } from "../../../../src/fake_data/entity"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; const ENTITIES = [ getEntity("light", "bed_light", "on", { @@ -75,7 +75,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-area-card") +@customElement("demo-lovelace-area-card") class DemoArea extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -151,6 +151,6 @@ class DemoArea extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-area-card": DemoArea; + "demo-lovelace-area-card": DemoArea; } } diff --git a/gallery/src/demos/demo-hui-conditional-card.ts b/gallery/src/demos/lovelace/conditional-card.ts similarity index 85% rename from gallery/src/demos/demo-hui-conditional-card.ts rename to gallery/src/demos/lovelace/conditional-card.ts index 5977ee3c09..bdaf093ed3 100644 --- a/gallery/src/demos/demo-hui-conditional-card.ts +++ b/gallery/src/demos/lovelace/conditional-card.ts @@ -1,8 +1,8 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { getEntity } from "../../../src/fake_data/entity"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; +import { getEntity } from "../../../../src/fake_data/entity"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; const ENTITIES = [ getEntity("light", "controller_1", "on", { @@ -52,7 +52,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-conditional-card") +@customElement("demo-lovelace-conditional-card") class DemoConditional extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -71,6 +71,6 @@ class DemoConditional extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-conditional-card": DemoConditional; + "demo-lovelace-conditional-card": DemoConditional; } } diff --git a/gallery/src/demos/demo-hui-entities-card.ts b/gallery/src/demos/lovelace/entities-card.ts similarity index 95% rename from gallery/src/demos/demo-hui-entities-card.ts rename to gallery/src/demos/lovelace/entities-card.ts index c6ed878c0f..aab189d215 100644 --- a/gallery/src/demos/demo-hui-entities-card.ts +++ b/gallery/src/demos/lovelace/entities-card.ts @@ -1,8 +1,8 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { getEntity } from "../../../src/fake_data/entity"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; +import { getEntity } from "../../../../src/fake_data/entity"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; const ENTITIES = [ getEntity("light", "bed_light", "on", { @@ -216,7 +216,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-entities-card") +@customElement("demo-lovelace-entities-card") class DemoEntities extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -235,6 +235,6 @@ class DemoEntities extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-entities-card": DemoEntities; + "demo-lovelace-entities-card": DemoEntities; } } diff --git a/gallery/src/demos/demo-hui-entity-button-card.ts b/gallery/src/demos/lovelace/entity-button-card.ts similarity index 85% rename from gallery/src/demos/demo-hui-entity-button-card.ts rename to gallery/src/demos/lovelace/entity-button-card.ts index 320eb8f8c1..8718629399 100644 --- a/gallery/src/demos/demo-hui-entity-button-card.ts +++ b/gallery/src/demos/lovelace/entity-button-card.ts @@ -1,8 +1,8 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { getEntity } from "../../../src/fake_data/entity"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; +import { getEntity } from "../../../../src/fake_data/entity"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; const ENTITIES = [ getEntity("light", "bed_light", "on", { @@ -68,7 +68,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-entity-button-card") +@customElement("demo-lovelace-entity-button-card") class DemoButtonEntity extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -87,6 +87,6 @@ class DemoButtonEntity extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-entity-button-card": DemoButtonEntity; + "demo-lovelace-entity-button-card": DemoButtonEntity; } } diff --git a/gallery/src/demos/demo-hui-entity-filter-card.ts b/gallery/src/demos/lovelace/entity-filter-card.ts similarity index 91% rename from gallery/src/demos/demo-hui-entity-filter-card.ts rename to gallery/src/demos/lovelace/entity-filter-card.ts index 3a0162ae7b..879cf3bb71 100644 --- a/gallery/src/demos/demo-hui-entity-filter-card.ts +++ b/gallery/src/demos/lovelace/entity-filter-card.ts @@ -1,8 +1,8 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { getEntity } from "../../../src/fake_data/entity"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; +import { getEntity } from "../../../../src/fake_data/entity"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; const ENTITIES = [ getEntity("device_tracker", "demo_paulus", "work", { @@ -109,7 +109,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-entity-filter-card") +@customElement("demo-lovelace-entity-filter-card") class DemoEntityFilter extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -128,6 +128,6 @@ class DemoEntityFilter extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-entity-filter-card": DemoEntityFilter; + "demo-lovelace-entity-filter-card": DemoEntityFilter; } } diff --git a/gallery/src/demos/demo-hui-gauge-card.ts b/gallery/src/demos/lovelace/gauge-card.ts similarity index 90% rename from gallery/src/demos/demo-hui-gauge-card.ts rename to gallery/src/demos/lovelace/gauge-card.ts index fdcf07188d..9094f678b8 100644 --- a/gallery/src/demos/demo-hui-gauge-card.ts +++ b/gallery/src/demos/lovelace/gauge-card.ts @@ -1,8 +1,8 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { getEntity } from "../../../src/fake_data/entity"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; +import { getEntity } from "../../../../src/fake_data/entity"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; const ENTITIES = [ getEntity("sensor", "brightness", "12", {}), @@ -106,7 +106,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-gauge-card") +@customElement("demo-lovelace-gauge-card") class DemoGaugeEntity extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -125,6 +125,6 @@ class DemoGaugeEntity extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-gauge-card": DemoGaugeEntity; + "demo-lovelace-gauge-card": DemoGaugeEntity; } } diff --git a/gallery/src/demos/demo-hui-glance-card.ts b/gallery/src/demos/lovelace/glance-card.ts similarity index 95% rename from gallery/src/demos/demo-hui-glance-card.ts rename to gallery/src/demos/lovelace/glance-card.ts index c078ba5f61..1e4d0755df 100644 --- a/gallery/src/demos/demo-hui-glance-card.ts +++ b/gallery/src/demos/lovelace/glance-card.ts @@ -1,8 +1,8 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { getEntity } from "../../../src/fake_data/entity"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; +import { getEntity } from "../../../../src/fake_data/entity"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; const ENTITIES = [ getEntity("device_tracker", "demo_paulus", "home", { @@ -209,7 +209,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-glance-card") +@customElement("demo-lovelace-glance-card") class DemoGlanceEntity extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -228,6 +228,6 @@ class DemoGlanceEntity extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-glance-card": DemoGlanceEntity; + "demo-lovelace-glance-card": DemoGlanceEntity; } } diff --git a/gallery/src/demos/demo-hui-grid-and-stack-card.ts b/gallery/src/demos/lovelace/grid-and-stack-card.ts similarity index 93% rename from gallery/src/demos/demo-hui-grid-and-stack-card.ts rename to gallery/src/demos/lovelace/grid-and-stack-card.ts index 6b743b243f..9fc7d6f5e7 100644 --- a/gallery/src/demos/demo-hui-grid-and-stack-card.ts +++ b/gallery/src/demos/lovelace/grid-and-stack-card.ts @@ -1,9 +1,9 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { mockHistory } from "../../../demo/src/stubs/history"; -import { getEntity } from "../../../src/fake_data/entity"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; +import { mockHistory } from "../../../../demo/src/stubs/history"; +import { getEntity } from "../../../../src/fake_data/entity"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; const ENTITIES = [ getEntity("light", "kitchen_lights", "on", { @@ -199,7 +199,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-grid-and-stack-card") +@customElement("demo-lovelace-grid-and-stack-card") class DemoStack extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -219,6 +219,6 @@ class DemoStack extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-grid-and-stack-card": DemoStack; + "demo-lovelace-grid-and-stack-card": DemoStack; } } diff --git a/gallery/src/demos/demo-hui-iframe-card.ts b/gallery/src/demos/lovelace/iframe-card.ts similarity index 84% rename from gallery/src/demos/demo-hui-iframe-card.ts rename to gallery/src/demos/lovelace/iframe-card.ts index 32d7e39140..72800f6407 100644 --- a/gallery/src/demos/demo-hui-iframe-card.ts +++ b/gallery/src/demos/lovelace/iframe-card.ts @@ -1,7 +1,7 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; const CONFIGS = [ { @@ -37,7 +37,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-iframe-card") +@customElement("demo-lovelace-iframe-card") class DemoIframe extends LitElement { @query("demo-cards") private _demos!: HTMLElement; @@ -53,6 +53,6 @@ class DemoIframe extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-iframe-card": DemoIframe; + "demo-lovelace-iframe-card": DemoIframe; } } diff --git a/gallery/src/demos/demo-hui-light-card.ts b/gallery/src/demos/lovelace/light-card.ts similarity index 86% rename from gallery/src/demos/demo-hui-light-card.ts rename to gallery/src/demos/lovelace/light-card.ts index 8cae0ff9d7..3b0fc01011 100644 --- a/gallery/src/demos/demo-hui-light-card.ts +++ b/gallery/src/demos/lovelace/light-card.ts @@ -1,8 +1,8 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { getEntity } from "../../../src/fake_data/entity"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; +import { getEntity } from "../../../../src/fake_data/entity"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; const ENTITIES = [ getEntity("light", "bed_light", "on", { @@ -62,7 +62,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-light-card") +@customElement("demo-lovelace-light-card") class DemoLightEntity extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -81,6 +81,6 @@ class DemoLightEntity extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-light-card": DemoLightEntity; + "demo-lovelace-light-card": DemoLightEntity; } } diff --git a/gallery/src/demos/demo-hui-map-card.ts b/gallery/src/demos/lovelace/map-card.ts similarity index 93% rename from gallery/src/demos/demo-hui-map-card.ts rename to gallery/src/demos/lovelace/map-card.ts index 68912a6e77..db83496bf7 100644 --- a/gallery/src/demos/demo-hui-map-card.ts +++ b/gallery/src/demos/lovelace/map-card.ts @@ -1,8 +1,8 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { getEntity } from "../../../src/fake_data/entity"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; +import { getEntity } from "../../../../src/fake_data/entity"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; const ENTITIES = [ getEntity("device_tracker", "demo_paulus", "not_home", { @@ -160,7 +160,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-map-card") +@customElement("demo-lovelace-map-card") class DemoMap extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -179,6 +179,6 @@ class DemoMap extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-map-card": DemoMap; + "demo-lovelace-map-card": DemoMap; } } diff --git a/gallery/src/demos/demo-hui-markdown-card.ts b/gallery/src/demos/lovelace/markdown-card.ts similarity index 95% rename from gallery/src/demos/demo-hui-markdown-card.ts rename to gallery/src/demos/lovelace/markdown-card.ts index 6e34a04c6f..2b6257cd23 100644 --- a/gallery/src/demos/demo-hui-markdown-card.ts +++ b/gallery/src/demos/lovelace/markdown-card.ts @@ -1,8 +1,8 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { mockTemplate } from "../../../demo/src/stubs/template"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; +import { mockTemplate } from "../../../../demo/src/stubs/template"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; const CONFIGS = [ { @@ -253,7 +253,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-markdown-card") +@customElement("demo-lovelace-markdown-card") class DemoMarkdown extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -272,6 +272,6 @@ class DemoMarkdown extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-markdown-card": DemoMarkdown; + "demo-lovelace-markdown-card": DemoMarkdown; } } diff --git a/gallery/src/demos/demo-hui-media-control-card.ts b/gallery/src/demos/lovelace/media-control-card.ts similarity index 92% rename from gallery/src/demos/demo-hui-media-control-card.ts rename to gallery/src/demos/lovelace/media-control-card.ts index 0b963f36e8..9fb7ab7b5b 100644 --- a/gallery/src/demos/demo-hui-media-control-card.ts +++ b/gallery/src/demos/lovelace/media-control-card.ts @@ -1,8 +1,8 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; -import { createMediaPlayerEntities } from "../data/media_players"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; +import { createMediaPlayerEntities } from "../../data/media_players"; const CONFIGS = [ { @@ -157,7 +157,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-media-control-card") +@customElement("demo-lovelace-media-control-card") class DemoHuiMediaControlCard extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -176,6 +176,6 @@ class DemoHuiMediaControlCard extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-media-control-card": DemoHuiMediaControlCard; + "demo-lovelace-media-control-card": DemoHuiMediaControlCard; } } diff --git a/gallery/src/demos/demo-hui-media-player-row.ts b/gallery/src/demos/lovelace/media-player-row.ts similarity index 88% rename from gallery/src/demos/demo-hui-media-player-row.ts rename to gallery/src/demos/lovelace/media-player-row.ts index f99b20fcdf..44433bc089 100644 --- a/gallery/src/demos/demo-hui-media-player-row.ts +++ b/gallery/src/demos/lovelace/media-player-row.ts @@ -1,8 +1,8 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; -import { createMediaPlayerEntities } from "../data/media_players"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; +import { createMediaPlayerEntities } from "../../data/media_players"; const CONFIGS = [ { @@ -54,7 +54,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-media-player-row") +@customElement("demo-lovelace-media-player-row") class DemoHuiMediaPlayerRow extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -73,6 +73,6 @@ class DemoHuiMediaPlayerRow extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-media-player-rows": DemoHuiMediaPlayerRow; + "demo-lovelace-media-player-rows": DemoHuiMediaPlayerRow; } } diff --git a/gallery/src/demos/demo-hui-picture-elements-card.ts b/gallery/src/demos/lovelace/picture-elements-card.ts similarity index 92% rename from gallery/src/demos/demo-hui-picture-elements-card.ts rename to gallery/src/demos/lovelace/picture-elements-card.ts index c3fcc7d61b..f1f5941157 100644 --- a/gallery/src/demos/demo-hui-picture-elements-card.ts +++ b/gallery/src/demos/lovelace/picture-elements-card.ts @@ -1,8 +1,8 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { getEntity } from "../../../src/fake_data/entity"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; +import { getEntity } from "../../../../src/fake_data/entity"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; const ENTITIES = [ getEntity("light", "bed_light", "on", { @@ -124,7 +124,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-picture-elements-card") +@customElement("demo-lovelace-picture-elements-card") class DemoPictureElements extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -143,6 +143,6 @@ class DemoPictureElements extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-picture-elements-card": DemoPictureElements; + "demo-lovelace-picture-elements-card": DemoPictureElements; } } diff --git a/gallery/src/demos/demo-hui-picture-entity-card.ts b/gallery/src/demos/lovelace/picture-entity-card.ts similarity index 87% rename from gallery/src/demos/demo-hui-picture-entity-card.ts rename to gallery/src/demos/lovelace/picture-entity-card.ts index 6b8d8418e1..b88d97cbce 100644 --- a/gallery/src/demos/demo-hui-picture-entity-card.ts +++ b/gallery/src/demos/lovelace/picture-entity-card.ts @@ -1,8 +1,8 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { getEntity } from "../../../src/fake_data/entity"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; +import { getEntity } from "../../../../src/fake_data/entity"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; const ENTITIES = [ getEntity("light", "kitchen_lights", "on", { @@ -79,7 +79,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-picture-entity-card") +@customElement("demo-lovelace-picture-entity-card") class DemoPictureEntity extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -98,6 +98,6 @@ class DemoPictureEntity extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-picture-entity-card": DemoPictureEntity; + "demo-lovelace-picture-entity-card": DemoPictureEntity; } } diff --git a/gallery/src/demos/demo-hui-picture-glance-card.ts b/gallery/src/demos/lovelace/picture-glance-card.ts similarity index 91% rename from gallery/src/demos/demo-hui-picture-glance-card.ts rename to gallery/src/demos/lovelace/picture-glance-card.ts index b82c2a2fa9..f698754ea6 100644 --- a/gallery/src/demos/demo-hui-picture-glance-card.ts +++ b/gallery/src/demos/lovelace/picture-glance-card.ts @@ -1,8 +1,8 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { getEntity } from "../../../src/fake_data/entity"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; +import { getEntity } from "../../../../src/fake_data/entity"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; const ENTITIES = [ getEntity("switch", "decorative_lights", "on", { @@ -120,7 +120,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-picture-glance-card") +@customElement("demo-lovelace-picture-glance-card") class DemoPictureGlance extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -139,6 +139,6 @@ class DemoPictureGlance extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-picture-glance-card": DemoPictureGlance; + "demo-lovelace-picture-glance-card": DemoPictureGlance; } } diff --git a/gallery/src/demos/demo-hui-plant-card.ts b/gallery/src/demos/lovelace/plant-card.ts similarity index 81% rename from gallery/src/demos/demo-hui-plant-card.ts rename to gallery/src/demos/lovelace/plant-card.ts index 683d0c6a37..99b6780aee 100644 --- a/gallery/src/demos/demo-hui-plant-card.ts +++ b/gallery/src/demos/lovelace/plant-card.ts @@ -1,8 +1,8 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; -import { createPlantEntities } from "../data/plants"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; +import { createPlantEntities } from "../../data/plants"; const CONFIGS = [ { @@ -29,7 +29,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-plant-card") +@customElement("demo-lovelace-plant-card") export class DemoPlantEntity extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -48,6 +48,6 @@ export class DemoPlantEntity extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-plant-card": DemoPlantEntity; + "demo-lovelace-plant-card": DemoPlantEntity; } } diff --git a/gallery/src/demos/demo-hui-shopping-list-card.ts b/gallery/src/demos/lovelace/shopping-list-card.ts similarity index 83% rename from gallery/src/demos/demo-hui-shopping-list-card.ts rename to gallery/src/demos/lovelace/shopping-list-card.ts index 034c150abd..68b0894516 100644 --- a/gallery/src/demos/demo-hui-shopping-list-card.ts +++ b/gallery/src/demos/lovelace/shopping-list-card.ts @@ -1,7 +1,7 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; const CONFIGS = [ { @@ -19,7 +19,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-shopping-list-card") +@customElement("demo-lovelace-shopping-list-card") class DemoShoppingListEntity extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -44,6 +44,6 @@ class DemoShoppingListEntity extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-shopping-list-card": DemoShoppingListEntity; + "demo-lovelace-shopping-list-card": DemoShoppingListEntity; } } diff --git a/gallery/src/demos/demo-hui-thermostat-card.ts b/gallery/src/demos/lovelace/thermostat-card.ts similarity index 88% rename from gallery/src/demos/demo-hui-thermostat-card.ts rename to gallery/src/demos/lovelace/thermostat-card.ts index 86216da564..cc33346a0e 100644 --- a/gallery/src/demos/demo-hui-thermostat-card.ts +++ b/gallery/src/demos/lovelace/thermostat-card.ts @@ -1,8 +1,8 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, query } from "lit/decorators"; -import { getEntity } from "../../../src/fake_data/entity"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import "../components/demo-cards"; +import { getEntity } from "../../../../src/fake_data/entity"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-cards"; const ENTITIES = [ getEntity("climate", "ecobee", "auto", { @@ -73,7 +73,7 @@ const CONFIGS = [ }, ]; -@customElement("demo-hui-thermostat-card") +@customElement("demo-lovelace-thermostat-card") class DemoThermostatEntity extends LitElement { @query("#demos") private _demoRoot!: HTMLElement; @@ -92,6 +92,6 @@ class DemoThermostatEntity extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-hui-thermostat-card": DemoThermostatEntity; + "demo-lovelace-thermostat-card": DemoThermostatEntity; } } diff --git a/gallery/src/demos/demo-more-info-cover.ts b/gallery/src/demos/more-info/cover.ts similarity index 93% rename from gallery/src/demos/demo-more-info-cover.ts rename to gallery/src/demos/more-info/cover.ts index f715d5fc9c..6afa1a6ff9 100644 --- a/gallery/src/demos/demo-more-info-cover.ts +++ b/gallery/src/demos/more-info/cover.ts @@ -1,6 +1,6 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, property, query } from "lit/decorators"; -import "../../../src/components/ha-card"; +import "../../../../src/components/ha-card"; import { SUPPORT_OPEN, SUPPORT_STOP, @@ -10,14 +10,14 @@ import { SUPPORT_STOP_TILT, SUPPORT_CLOSE_TILT, SUPPORT_SET_TILT_POSITION, -} from "../../../src/data/cover"; -import "../../../src/dialogs/more-info/more-info-content"; -import { getEntity } from "../../../src/fake_data/entity"; +} from "../../../../src/data/cover"; +import "../../../../src/dialogs/more-info/more-info-content"; +import { getEntity } from "../../../../src/fake_data/entity"; import { MockHomeAssistant, provideHass, -} from "../../../src/fake_data/provide_hass"; -import "../components/demo-more-infos"; +} from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-more-infos"; const ENTITIES = [ getEntity("cover", "position_buttons", "on", { diff --git a/gallery/src/demos/demo-more-info-light.ts b/gallery/src/demos/more-info/light.ts similarity index 93% rename from gallery/src/demos/demo-more-info-light.ts rename to gallery/src/demos/more-info/light.ts index a3107a5df3..530b95909e 100644 --- a/gallery/src/demos/demo-more-info-light.ts +++ b/gallery/src/demos/more-info/light.ts @@ -1,19 +1,19 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, property, query } from "lit/decorators"; -import "../../../src/components/ha-card"; +import "../../../../src/components/ha-card"; import { LightColorModes, SUPPORT_EFFECT, SUPPORT_FLASH, SUPPORT_TRANSITION, -} from "../../../src/data/light"; -import "../../../src/dialogs/more-info/more-info-content"; -import { getEntity } from "../../../src/fake_data/entity"; +} from "../../../../src/data/light"; +import "../../../../src/dialogs/more-info/more-info-content"; +import { getEntity } from "../../../../src/fake_data/entity"; import { MockHomeAssistant, provideHass, -} from "../../../src/fake_data/provide_hass"; -import "../components/demo-more-infos"; +} from "../../../../src/fake_data/provide_hass"; +import "../../components/demo-more-infos"; const ENTITIES = [ getEntity("light", "bed_light", "on", { diff --git a/gallery/src/demos/demo-integration-card.ts b/gallery/src/demos/rest/integration-card.ts similarity index 91% rename from gallery/src/demos/demo-integration-card.ts rename to gallery/src/demos/rest/integration-card.ts index 5067d6e455..b00760485e 100644 --- a/gallery/src/demos/demo-integration-card.ts +++ b/gallery/src/demos/rest/integration-card.ts @@ -1,22 +1,22 @@ import { html, css, LitElement, TemplateResult } from "lit"; -import "../../../src/components/ha-formfield"; -import "../../../src/components/ha-switch"; +import "../../../../src/components/ha-formfield"; +import "../../../../src/components/ha-switch"; import { classMap } from "lit/directives/class-map"; import { customElement, property, state } from "lit/decorators"; -import { IntegrationManifest } from "../../../src/data/integration"; +import { IntegrationManifest } from "../../../../src/data/integration"; -import { provideHass } from "../../../src/fake_data/provide_hass"; -import { HomeAssistant } from "../../../src/types"; -import "../../../src/panels/config/integrations/ha-integration-card"; -import "../../../src/panels/config/integrations/ha-ignored-config-entry-card"; -import "../../../src/panels/config/integrations/ha-config-flow-card"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import { HomeAssistant } from "../../../../src/types"; +import "../../../../src/panels/config/integrations/ha-integration-card"; +import "../../../../src/panels/config/integrations/ha-ignored-config-entry-card"; +import "../../../../src/panels/config/integrations/ha-config-flow-card"; import type { ConfigEntryExtended, DataEntryFlowProgressExtended, -} from "../../../src/panels/config/integrations/ha-config-integrations"; -import { DeviceRegistryEntry } from "../../../src/data/device_registry"; -import { EntityRegistryEntry } from "../../../src/data/entity_registry"; +} from "../../../../src/panels/config/integrations/ha-config-integrations"; +import { DeviceRegistryEntry } from "../../../../src/data/device_registry"; +import { EntityRegistryEntry } from "../../../../src/data/entity_registry"; const createConfigEntry = ( title: string, @@ -217,7 +217,7 @@ const createDeviceRegistryEntries = ( }, ]; -@customElement("demo-integration-card") +@customElement("demo-rest-integration-card") export class DemoIntegrationCard extends LitElement { @property({ attribute: false }) hass?: HomeAssistant; @@ -352,6 +352,6 @@ export class DemoIntegrationCard extends LitElement { declare global { interface HTMLElementTagNameMap { - "demo-integration-card": DemoIntegrationCard; + "demo-rest-integration-card": DemoIntegrationCard; } } diff --git a/gallery/src/demos/demo-util-long-press.ts b/gallery/src/demos/rest/util-long-press.ts similarity index 83% rename from gallery/src/demos/demo-util-long-press.ts rename to gallery/src/demos/rest/util-long-press.ts index d7851dcefd..0188cf0af7 100644 --- a/gallery/src/demos/demo-util-long-press.ts +++ b/gallery/src/demos/rest/util-long-press.ts @@ -1,11 +1,11 @@ import "@material/mwc-button"; import { css, html, LitElement, TemplateResult } from "lit"; import { customElement } from "lit/decorators"; -import "../../../src/components/ha-card"; -import { ActionHandlerEvent } from "../../../src/data/lovelace"; -import { actionHandler } from "../../../src/panels/lovelace/common/directives/action-handler-directive"; +import "../../../../src/components/ha-card"; +import { ActionHandlerEvent } from "../../../../src/data/lovelace"; +import { actionHandler } from "../../../../src/panels/lovelace/common/directives/action-handler-directive"; -@customElement("demo-util-long-press") +@customElement("demo-rest-util-long-press") export class DemoUtilLongPress extends LitElement { protected render(): TemplateResult { return html` diff --git a/gallery/src/ha-gallery.ts b/gallery/src/ha-gallery.ts index 2aa583ca12..0454111a16 100644 --- a/gallery/src/ha-gallery.ts +++ b/gallery/src/ha-gallery.ts @@ -3,14 +3,16 @@ import "@material/mwc-drawer"; import "@material/mwc-top-app-bar-fixed"; import { html, css, LitElement, PropertyValues } from "lit"; import { customElement, property, query } from "lit/decorators"; -import { until } from "lit/directives/until"; import "../../src/components/ha-card"; import "../../src/components/ha-icon-button"; import "../../src/managers/notification-manager"; import { haStyle } from "../../src/resources/styles"; -import { DEMOS } from "../build/import-demos"; +import { DEMOS, SIDEBAR } from "../build/import-demos"; import { dynamicElement } from "../../src/common/dom/dynamic-element-directive"; -import { SIDEBAR } from "./sidebar"; +import "./components/demo-description"; + +const GITHUB_DEMO_URL = + "https://github.com/home-assistant/frontend/blob/dev/gallery/src/demos/"; const FAKE_HASS = { // Just enough for computeRTL for notification-manager @@ -23,7 +25,8 @@ const FAKE_HASS = { @customElement("ha-gallery") class HaGallery extends LitElement { @property() private _demo = - document.location.hash.substring(1) || SIDEBAR[0].demos![0]; + document.location.hash.substring(1) || + `${SIDEBAR[0].category}/${SIDEBAR[0].demos![0]}`; @query("notification-manager") private _notifications!: HTMLElementTagNameMap["notification-manager"]; @@ -37,28 +40,21 @@ class HaGallery extends LitElement { const sidebar: unknown[] = []; for (const group of SIDEBAR) { - let sectionOpen = false; const links: unknown[] = []; for (const demo of group.demos!) { - const active = this._demo === demo; - if (active) { - sectionOpen = true; - } - + const key = `${group.category}/${demo}`; + const active = this._demo === key; + const title = DEMOS[key].metadata.title || demo; links.push(html` - ${group.demoStart === undefined - ? demo - : demo.substring(group.demoStart.length)} + ${title} `); } sidebar.push( group.header ? html` -
+
${group.header} ${links}
@@ -84,24 +80,36 @@ class HaGallery extends LitElement { .path=${mdiMenu} > -
${this._demo}
+
+ ${DEMOS[this._demo].metadata.title || this._demo.split("/")[1]} +
- ${DEMOS[this._demo].description - ? html` - ${until( - DEMOS[this._demo].description().then( - (content) => html` - -
${content}
-
- ` - ), - "" - )} - ` - : ""} - ${dynamicElement(`demo-${this._demo}`)} + + ${dynamicElement(`demo-${this._demo.replace("/", "-")}`)} +
@@ -143,6 +151,13 @@ class HaGallery extends LitElement { super.updated(changedProps); if (changedProps.has("_demo") && DEMOS[this._demo].load) { DEMOS[this._demo].load(); + const menuItem = this.shadowRoot!.querySelector( + `a[href="#${this._demo}"]` + )!; + // Make sure section is expanded + if (menuItem.parentElement instanceof HTMLDetailsElement) { + menuItem.parentElement.open = true; + } } } @@ -196,9 +211,14 @@ class HaGallery extends LitElement { opacity: 0.12; } - ha-card { - max-width: 600px; - margin: 16px auto; + .demo-footer { + text-align: center; + margin: 16px 0; + } + + .demo-footer a { + display: inline-block; + margin: 0 8px; } `, ]; diff --git a/gallery/src/sidebar.ts b/gallery/src/sidebar.ts deleted file mode 100644 index 71222f59a0..0000000000 --- a/gallery/src/sidebar.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { DEMOS } from "../build/import-demos"; - -export const SIDEBAR: SidebarSection[] = [ - { - demos: ["introduction"], - }, - - { - // Each section has a header - header: "Lovelace", - // Specify demos to make sure they are put on top. - demos: [], - // Add a demoStart to automatically gather demos based on their name - demoStart: "hui-", - }, - { - header: "Automation", - demoStart: "automation-", - }, - { - header: "Components", - demos: [ - "ha-alert", - "ha-bar", - "ha-chips", - "ha-faded", - "ha-form", - "ha-label-badge", - "ha-selector", - ], - }, - { - header: "More Info", - demoStart: "more-info-", - }, - { - header: "Rest", - demoStart: "", // empty string matches all. - }, -]; - -interface SidebarSection { - header?: string; - demos?: string[]; - demoStart?: string; -} - -const demosToProcess = new Set(Object.keys(DEMOS)); - -for (const group of Object.values(SIDEBAR)) { - // Any pre-defined groups will not be sorted. - if (group.demos) { - for (const demo of group.demos) { - demosToProcess.delete(demo); - } - } else { - group.demos = []; - } -} -for (const group of Object.values(SIDEBAR)) { - if (group.demoStart !== undefined) { - for (const demo of demosToProcess) { - if (demo.startsWith(group.demoStart)) { - group.demos!.push(demo); - demosToProcess.delete(demo); - } - } - } -} diff --git a/package.json b/package.json index 0c0125cb79..f95e8b856f 100644 --- a/package.json +++ b/package.json @@ -162,6 +162,7 @@ "@rollup/plugin-replace": "^2.3.2", "@types/chromecast-caf-receiver": "5.0.12", "@types/chromecast-caf-sender": "^1.0.3", + "@types/glob": "^7", "@types/js-yaml": "^4", "@types/leaflet": "^1", "@types/leaflet-draw": "^1", @@ -189,6 +190,7 @@ "eslint-plugin-wc": "^1.3.2", "fancy-log": "^1.3.3", "fs-extra": "^7.0.1", + "glob": "^7.2.0", "gulp": "^4.0.2", "gulp-foreach": "^0.1.0", "gulp-json-transform": "^0.4.6", diff --git a/yarn.lock b/yarn.lock index 285de20715..c2783d2021 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3803,13 +3803,6 @@ __metadata: languageName: node linkType: hard -"@types/events@npm:*": - version: 3.0.0 - resolution: "@types/events@npm:3.0.0" - checksum: 9a424c2da210957d5636e0763e8c9fc3aaeee35bf411284ddec62a56a6abe31de9c7c2e713dabdd8a76ff98b47db2bd52f61310be6609641d6234cc842ecbbe3 - languageName: node - linkType: hard - "@types/express-serve-static-core@npm:*": version: 4.17.13 resolution: "@types/express-serve-static-core@npm:4.17.13" @@ -3856,14 +3849,13 @@ __metadata: languageName: node linkType: hard -"@types/glob@npm:^7.1.1": - version: 7.1.1 - resolution: "@types/glob@npm:7.1.1" +"@types/glob@npm:^7, @types/glob@npm:^7.1.1": + version: 7.2.0 + resolution: "@types/glob@npm:7.2.0" dependencies: - "@types/events": "*" "@types/minimatch": "*" "@types/node": "*" - checksum: 9fb96d004c8e9ed25b305bc0d34c99c70c47c571740ca861cca92be4b28649786971703e9883f8ead0815b50225dbaf103a1df2d076923066f6bc0ab733a7be8 + checksum: 6ae717fedfdfdad25f3d5a568323926c64f52ef35897bcac8aca8e19bc50c0bd84630bbd063e5d52078b2137d8e7d3c26eabebd1a2f03ff350fff8a91e79fc19 languageName: node linkType: hard @@ -8666,9 +8658,9 @@ fsevents@^1.2.7: languageName: node linkType: hard -"glob@npm:^7.0.3, glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6": - version: 7.1.7 - resolution: "glob@npm:7.1.7" +"glob@npm:^7.0.3, glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.2.0": + version: 7.2.0 + resolution: "glob@npm:7.2.0" dependencies: fs.realpath: ^1.0.0 inflight: ^1.0.4 @@ -8676,7 +8668,7 @@ fsevents@^1.2.7: minimatch: ^3.0.4 once: ^1.3.0 path-is-absolute: ^1.0.0 - checksum: b61f48973bbdcf5159997b0874a2165db572b368b931135832599875919c237fc05c12984e38fe828e69aa8a921eb0e8a4997266211c517c9cfaae8a93988bb8 + checksum: 78a8ea942331f08ed2e055cb5b9e40fe6f46f579d7fd3d694f3412fe5db23223d29b7fee1575440202e9a7ff9a72ab106a39fee39934c7bedafe5e5f8ae20134 languageName: node linkType: hard @@ -9123,6 +9115,7 @@ fsevents@^1.2.7: "@thomasloven/round-slider": 0.5.4 "@types/chromecast-caf-receiver": 5.0.12 "@types/chromecast-caf-sender": ^1.0.3 + "@types/glob": ^7 "@types/js-yaml": ^4 "@types/leaflet": ^1 "@types/leaflet-draw": ^1 @@ -9165,6 +9158,7 @@ fsevents@^1.2.7: fancy-log: ^1.3.3 fs-extra: ^7.0.1 fuse.js: ^6.0.0 + glob: ^7.2.0 google-timezones-json: ^1.0.2 gulp: ^4.0.2 gulp-foreach: ^0.1.0 From 3133f9b01f459e52592804e072bf67bfa9e8303d Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 6 Jan 2022 22:32:10 -0800 Subject: [PATCH 008/127] Use page instead of demo (#11118) * Use page instead of demo * Update netlify script * Update ci.yml * Rename demo -> page --- .github/workflows/ci.yaml | 2 +- build-scripts/gulp/gallery.js | 76 +++++++++--------- gallery/script/netlify_build_gallery | 6 +- gallery/sidebar.js | 32 ++++---- gallery/src/components/demo-description.ts | 44 ---------- gallery/src/components/page-description.ts | 50 ++++++++++++ gallery/src/ha-gallery.ts | 69 ++++++++-------- gallery/src/html/index.html.template | 2 +- .../automation/describe-action.ts | 0 .../automation/describe-condition.ts | 0 .../automation/describe-trigger.ts | 0 .../automation/editor-action.ts | 0 .../automation/editor-condition.ts | 0 .../automation/editor-trigger.ts | 0 .../automation/trace-timeline.ts | 0 .../src/{demos => pages}/automation/trace.ts | 0 .../components/ha-alert.markdown | 0 .../{demos => pages}/components/ha-alert.ts | 0 .../src/{demos => pages}/components/ha-bar.ts | 0 .../{demos => pages}/components/ha-chips.ts | 0 .../{demos => pages}/components/ha-faded.ts | 0 .../{demos => pages}/components/ha-form.ts | 0 .../components/ha-label-badge.ts | 0 .../components/ha-selector.ts | 0 gallery/src/pages/concepts/home.markdown | 7 ++ .../design.home-assistant.io/editing.markdown | 80 +++++++++++++++++++ .../lovelace/alarm-panel-card.markdown | 0 .../lovelace/alarm-panel-card.ts | 0 .../{demos => pages}/lovelace/area-card.ts | 0 .../lovelace/conditional-card.ts | 0 .../lovelace/entities-card.ts | 0 .../lovelace/entity-button-card.ts | 0 .../lovelace/entity-filter-card.ts | 0 .../{demos => pages}/lovelace/gauge-card.ts | 0 .../{demos => pages}/lovelace/glance-card.ts | 0 .../lovelace/grid-and-stack-card.ts | 0 .../{demos => pages}/lovelace/iframe-card.ts | 0 .../lovelace}/introduction.markdown | 0 .../{demos => pages}/lovelace/light-card.ts | 0 .../src/{demos => pages}/lovelace/map-card.ts | 0 .../lovelace/markdown-card.ts | 0 .../lovelace/media-control-card.ts | 0 .../lovelace/media-player-row.ts | 0 .../lovelace/picture-elements-card.ts | 0 .../lovelace/picture-entity-card.ts | 0 .../lovelace/picture-glance-card.ts | 0 .../{demos => pages}/lovelace/plant-card.ts | 0 .../lovelace/shopping-list-card.ts | 0 .../lovelace/thermostat-card.ts | 0 .../rest => pages/misc}/integration-card.ts | 0 .../rest => pages/misc}/util-long-press.ts | 0 .../src/{demos => pages}/more-info/cover.ts | 0 .../src/{demos => pages}/more-info/light.ts | 0 src/components/ha-markdown.ts | 18 ++--- 54 files changed, 242 insertions(+), 144 deletions(-) delete mode 100644 gallery/src/components/demo-description.ts create mode 100644 gallery/src/components/page-description.ts rename gallery/src/{demos => pages}/automation/describe-action.ts (100%) rename gallery/src/{demos => pages}/automation/describe-condition.ts (100%) rename gallery/src/{demos => pages}/automation/describe-trigger.ts (100%) rename gallery/src/{demos => pages}/automation/editor-action.ts (100%) rename gallery/src/{demos => pages}/automation/editor-condition.ts (100%) rename gallery/src/{demos => pages}/automation/editor-trigger.ts (100%) rename gallery/src/{demos => pages}/automation/trace-timeline.ts (100%) rename gallery/src/{demos => pages}/automation/trace.ts (100%) rename gallery/src/{demos => pages}/components/ha-alert.markdown (100%) rename gallery/src/{demos => pages}/components/ha-alert.ts (100%) rename gallery/src/{demos => pages}/components/ha-bar.ts (100%) rename gallery/src/{demos => pages}/components/ha-chips.ts (100%) rename gallery/src/{demos => pages}/components/ha-faded.ts (100%) rename gallery/src/{demos => pages}/components/ha-form.ts (100%) rename gallery/src/{demos => pages}/components/ha-label-badge.ts (100%) rename gallery/src/{demos => pages}/components/ha-selector.ts (100%) create mode 100644 gallery/src/pages/concepts/home.markdown create mode 100644 gallery/src/pages/design.home-assistant.io/editing.markdown rename gallery/src/{demos => pages}/lovelace/alarm-panel-card.markdown (100%) rename gallery/src/{demos => pages}/lovelace/alarm-panel-card.ts (100%) rename gallery/src/{demos => pages}/lovelace/area-card.ts (100%) rename gallery/src/{demos => pages}/lovelace/conditional-card.ts (100%) rename gallery/src/{demos => pages}/lovelace/entities-card.ts (100%) rename gallery/src/{demos => pages}/lovelace/entity-button-card.ts (100%) rename gallery/src/{demos => pages}/lovelace/entity-filter-card.ts (100%) rename gallery/src/{demos => pages}/lovelace/gauge-card.ts (100%) rename gallery/src/{demos => pages}/lovelace/glance-card.ts (100%) rename gallery/src/{demos => pages}/lovelace/grid-and-stack-card.ts (100%) rename gallery/src/{demos => pages}/lovelace/iframe-card.ts (100%) rename gallery/src/{demos/introduction => pages/lovelace}/introduction.markdown (100%) rename gallery/src/{demos => pages}/lovelace/light-card.ts (100%) rename gallery/src/{demos => pages}/lovelace/map-card.ts (100%) rename gallery/src/{demos => pages}/lovelace/markdown-card.ts (100%) rename gallery/src/{demos => pages}/lovelace/media-control-card.ts (100%) rename gallery/src/{demos => pages}/lovelace/media-player-row.ts (100%) rename gallery/src/{demos => pages}/lovelace/picture-elements-card.ts (100%) rename gallery/src/{demos => pages}/lovelace/picture-entity-card.ts (100%) rename gallery/src/{demos => pages}/lovelace/picture-glance-card.ts (100%) rename gallery/src/{demos => pages}/lovelace/plant-card.ts (100%) rename gallery/src/{demos => pages}/lovelace/shopping-list-card.ts (100%) rename gallery/src/{demos => pages}/lovelace/thermostat-card.ts (100%) rename gallery/src/{demos/rest => pages/misc}/integration-card.ts (100%) rename gallery/src/{demos/rest => pages/misc}/util-long-press.ts (100%) rename gallery/src/{demos => pages}/more-info/cover.ts (100%) rename gallery/src/{demos => pages}/more-info/light.ts (100%) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8948f51df5..4a67ddd5a0 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -30,7 +30,7 @@ jobs: env: CI: true - name: Build resources - run: ./node_modules/.bin/gulp gen-icons-json build-translations build-locale-data gather-gallery-demos + run: ./node_modules/.bin/gulp gen-icons-json build-translations build-locale-data gather-gallery-pages - name: Run eslint run: yarn run lint:eslint - name: Run tsc diff --git a/build-scripts/gulp/gallery.js b/build-scripts/gulp/gallery.js index 09ea380d7a..fcca2fc26e 100644 --- a/build-scripts/gulp/gallery.js +++ b/build-scripts/gulp/gallery.js @@ -19,14 +19,14 @@ require("./service-worker.js"); require("./entry-html.js"); require("./rollup.js"); -gulp.task("gather-gallery-demos", async function gatherDemos() { - const demoDir = path.resolve(paths.gallery_dir, "src/demos"); - const files = glob.sync(path.resolve(demoDir, "**/*")); +gulp.task("gather-gallery-pages", async function gatherPages() { + const pageDir = path.resolve(paths.gallery_dir, "src/pages"); + const files = glob.sync(path.resolve(pageDir, "**/*")); const galleryBuild = path.resolve(paths.gallery_dir, "build"); fs.mkdirSync(galleryBuild, { recursive: true }); - let content = "export const DEMOS = {\n"; + let content = "export const PAGES = {\n"; const processed = new Set(); @@ -34,17 +34,17 @@ gulp.task("gather-gallery-demos", async function gatherDemos() { if (fs.lstatSync(file).isDirectory()) { continue; } - demoId = file.substring(demoDir.length + 1, file.lastIndexOf(".")); + const pageId = file.substring(pageDir.length + 1, file.lastIndexOf(".")); - if (processed.has(demoId)) { + if (processed.has(pageId)) { continue; } - processed.add(demoId); + processed.add(pageId); - const [category, name] = demoId.split("/", 2); + const [category, name] = pageId.split("/", 2); - const demoFile = path.resolve(demoDir, `${demoId}.ts`); - const descriptionFile = path.resolve(demoDir, `${demoId}.markdown`); + const demoFile = path.resolve(pageDir, `${pageId}.ts`); + const descriptionFile = path.resolve(pageDir, `${pageId}.markdown`); const hasDemo = fs.existsSync(demoFile); let hasDescription = fs.existsSync(descriptionFile); let metadata = {}; @@ -63,24 +63,25 @@ gulp.task("gather-gallery-demos", async function gatherDemos() { if (descriptionContent === "") { hasDescription = false; } else { + descriptionContent = marked(descriptionContent).replace(/`/g, "\\`"); fs.mkdirSync(path.resolve(galleryBuild, category), { recursive: true }); fs.writeFileSync( - path.resolve(galleryBuild, `${demoId}-description.ts`), + path.resolve(galleryBuild, `${pageId}-description.ts`), ` import {html} from "lit"; - export default html\`${marked(descriptionContent)}\` + export default html\`${descriptionContent}\` ` ); } } - content += ` "${demoId}": { + content += ` "${pageId}": { metadata: ${JSON.stringify(metadata)}, ${ hasDescription - ? `description: () => import("./${demoId}-description").then(m => m.default),` + ? `description: () => import("./${pageId}-description").then(m => m.default),` : "" } - ${hasDemo ? `load: () => import("../src/demos/${demoId}")` : ""} + ${hasDemo ? `demo: () => import("../src/pages/${pageId}")` : ""} },\n`; } @@ -93,51 +94,54 @@ gulp.task("gather-gallery-demos", async function gatherDemos() { delete require.cache[sidebarPath]; const sidebar = require(sidebarPath); - const demosToProcess = {}; + const pagesToProcess = {}; for (const key of processed) { - const [category, demo] = key.split("/", 2); - if (!(category in demosToProcess)) { - demosToProcess[category] = new Set(); + const [category, page] = key.split("/", 2); + if (!(category in pagesToProcess)) { + pagesToProcess[category] = new Set(); } - demosToProcess[category].add(demo); + pagesToProcess[category].add(page); } for (const group of Object.values(sidebar)) { - const toProcess = demosToProcess[group.category]; - delete demosToProcess[group.category]; + const toProcess = pagesToProcess[group.category]; + delete pagesToProcess[group.category]; if (!toProcess) { console.error("Unknown category", group.category); + if (!group.pages) { + group.pages = []; + } continue; } // Any pre-defined groups will not be sorted. - if (group.demos) { - for (const demo of group.demos) { - if (!toProcess.delete(demo)) { - console.error("Found unreferenced demo", demo); + if (group.pages) { + for (const page of group.pages) { + if (!toProcess.delete(page)) { + console.error("Found unreferenced demo", page); } } } else { - group.demos = []; + group.pages = []; } - for (const demo of Array.from(toProcess).sort()) { - group.demos.push(demo); + for (const page of Array.from(toProcess).sort()) { + group.pages.push(page); } } - for (const [category, demos] of Object.entries(demosToProcess)) { + for (const [category, pages] of Object.entries(pagesToProcess)) { sidebar.push({ category, header: category, - demos: Array.from(demos), + pages: Array.from(pages).sort(), }); } content += `export const SIDEBAR = ${JSON.stringify(sidebar, null, 2)};\n`; fs.writeFileSync( - path.resolve(galleryBuild, "import-demos.ts"), + path.resolve(galleryBuild, "import-pages.ts"), content, "utf-8" ); @@ -155,7 +159,7 @@ gulp.task( "gen-icons-json", "build-translations", "build-locale-data", - "gather-gallery-demos" + "gather-gallery-pages" ), "copy-static-gallery", "gen-index-gallery-dev", @@ -166,10 +170,10 @@ gulp.task( async function watchMarkdownFiles() { gulp.watch( [ - path.resolve(paths.gallery_dir, "src/demos/**/*.markdown"), + path.resolve(paths.gallery_dir, "src/pages/**/*.markdown"), path.resolve(paths.gallery_dir, "sidebar.js"), ], - gulp.series("gather-gallery-demos") + gulp.series("gather-gallery-pages") ); } ) @@ -188,7 +192,7 @@ gulp.task( "gen-icons-json", "build-translations", "build-locale-data", - "gather-gallery-demos" + "gather-gallery-pages" ), "copy-static-gallery", env.useRollup() ? "rollup-prod-gallery" : "webpack-prod-gallery", diff --git a/gallery/script/netlify_build_gallery b/gallery/script/netlify_build_gallery index 173b77d73f..295486a2b1 100755 --- a/gallery/script/netlify_build_gallery +++ b/gallery/script/netlify_build_gallery @@ -1,6 +1,6 @@ #!/bin/bash -TARGET_LABEL="Needs gallery preview" +TARGET_LABEL="Needs design preview" if [[ "$NETLIFY" != "true" ]]; then echo "This script can only be run on Netlify" @@ -13,7 +13,7 @@ function createStatus() { target_url="$3" curl -X POST -H "Accept: application/vnd.github.v3+json" -H "Authorization: token $GITHUB_TOKEN" \ "https://api.github.com/repos/home-assistant/frontend/statuses/$COMMIT_REF" \ - -d '{"state": "'"${state}"'", "context": "Netlify/Gallery Preview Build", "description": "'"$description"'", "target_url": "'"$target_url"'"}' + -d '{"state": "'"${state}"'", "context": "Netlify/Design Preview Build", "description": "'"$description"'", "target_url": "'"$target_url"'"}' } @@ -22,7 +22,7 @@ if [[ "${PULL_REQUEST}" == "false" ]]; then else if [[ "$(curl -sSLf -H "Accept: application/vnd.github.v3+json" -H "Authorization: token $GITHUB_TOKEN" \ "https://api.github.com/repos/home-assistant/frontend/pulls/${REVIEW_ID}" | jq '.labels[].name' -r)" =~ "$TARGET_LABEL" ]]; then - createStatus "pending" "Building gallery preview" "https://app.netlify.com/sites/home-assistant-gallery/deploys/$BUILD_ID" + createStatus "pending" "Building design preview" "https://app.netlify.com/sites/home-assistant-gallery/deploys/$BUILD_ID" gulp build-gallery if [ $? -eq 0 ]; then createStatus "success" "Build complete" "$DEPLOY_URL" diff --git a/gallery/sidebar.js b/gallery/sidebar.js index 2d40478a88..978948eb85 100644 --- a/gallery/sidebar.js +++ b/gallery/sidebar.js @@ -1,16 +1,17 @@ module.exports = [ { - category: "introduction", - demos: ["introduction"], + // This section has no header and so all page links are shown directly in the sidebar + category: "concepts", + pages: ["home"], }, { category: "lovelace", - // Each section has a header + // Label for in the sidebar header: "Lovelace", - // Specify demos to make sure they are put on top. - demos: [], - // Add a demoStart to automatically gather demos based on their name + // Specify order of pages. Any pages in the category folder but not listed here will + // automatically be added after the pages listed here. + pages: ["introduction"], }, { category: "automation", @@ -19,22 +20,17 @@ module.exports = [ { category: "components", header: "Components", - demos: [ - "ha-alert", - "ha-bar", - "ha-chips", - "ha-faded", - "ha-form", - "ha-label-badge", - "ha-selector", - ], }, { category: "more-info", - header: "More Info", + header: "More Info dialogs", }, { - category: "rest", - header: "Rest", + category: "misc", + header: "Miscelaneous", + }, + { + category: "design.home-assistant.io", + header: "Design Documentation", }, ]; diff --git a/gallery/src/components/demo-description.ts b/gallery/src/components/demo-description.ts deleted file mode 100644 index 41dc6fc4a0..0000000000 --- a/gallery/src/components/demo-description.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { html, css, LitElement } from "lit"; -import { customElement, property } from "lit/decorators"; -import { until } from "lit/directives/until"; -import { haStyle } from "../../../src/resources/styles"; -import { DEMOS } from "../../build/import-demos"; - -@customElement("demo-description") -class DemoDescription extends LitElement { - @property() public demo!: string; - - render() { - if (!DEMOS[this.demo].description) { - return ""; - } - return html` - ${until( - DEMOS[this.demo].description().then( - (content) => html` - -
${content}
-
- ` - ), - "" - )} - `; - } - - static styles = [ - haStyle, - css` - ha-card { - max-width: 600px; - margin: 16px auto; - } - `, - ]; -} - -declare global { - interface HTMLElementTagNameMap { - "demo-description": DemoDescription; - } -} diff --git a/gallery/src/components/page-description.ts b/gallery/src/components/page-description.ts new file mode 100644 index 0000000000..abcdcc5820 --- /dev/null +++ b/gallery/src/components/page-description.ts @@ -0,0 +1,50 @@ +import { html, css } from "lit"; +import { customElement, property } from "lit/decorators"; +import { until } from "lit/directives/until"; +import { HaMarkdown } from "../../../src/components/ha-markdown"; +import { PAGES } from "../../build/import-pages"; + +@customElement("page-description") +class PageDescription extends HaMarkdown { + @property() public page!: string; + + render() { + if (!PAGES[this.page].description) { + return html``; + } + return html` + ${until( + PAGES[this.page].description().then( + (content) => html` + +
${content}
+
+ ` + ), + "" + )} + `; + } + + static styles = [ + HaMarkdown.styles, + css` + ha-card { + max-width: 600px; + margin: 16px auto; + } + .card-content > *:first-child { + margin-top: 0; + } + .card-content > *:last-child { + margin-bottom: 0; + } + `, + ]; +} + +declare global { + interface HTMLElementTagNameMap { + "page-description": PageDescription; + } +} diff --git a/gallery/src/ha-gallery.ts b/gallery/src/ha-gallery.ts index 0454111a16..553ba4479f 100644 --- a/gallery/src/ha-gallery.ts +++ b/gallery/src/ha-gallery.ts @@ -7,12 +7,12 @@ import "../../src/components/ha-card"; import "../../src/components/ha-icon-button"; import "../../src/managers/notification-manager"; import { haStyle } from "../../src/resources/styles"; -import { DEMOS, SIDEBAR } from "../build/import-demos"; +import { PAGES, SIDEBAR } from "../build/import-pages"; import { dynamicElement } from "../../src/common/dom/dynamic-element-directive"; -import "./components/demo-description"; +import "./components/page-description"; const GITHUB_DEMO_URL = - "https://github.com/home-assistant/frontend/blob/dev/gallery/src/demos/"; + "https://github.com/home-assistant/frontend/blob/dev/gallery/src/pages/"; const FAKE_HASS = { // Just enough for computeRTL for notification-manager @@ -24,9 +24,9 @@ const FAKE_HASS = { @customElement("ha-gallery") class HaGallery extends LitElement { - @property() private _demo = + @property() private _page = document.location.hash.substring(1) || - `${SIDEBAR[0].category}/${SIDEBAR[0].demos![0]}`; + `${SIDEBAR[0].category}/${SIDEBAR[0].pages![0]}`; @query("notification-manager") private _notifications!: HTMLElementTagNameMap["notification-manager"]; @@ -42,12 +42,12 @@ class HaGallery extends LitElement { for (const group of SIDEBAR) { const links: unknown[] = []; - for (const demo of group.demos!) { - const key = `${group.category}/${demo}`; - const active = this._demo === key; - const title = DEMOS[key].metadata.title || demo; + for (const page of group.pages!) { + const key = `${group.category}/${page}`; + const active = this._page === key; + const title = PAGES[key].metadata.title || page; links.push(html` - ${title} + ${title} `); } @@ -81,28 +81,28 @@ class HaGallery extends LitElement { >
- ${DEMOS[this._demo].metadata.title || this._demo.split("/")[1]} + ${PAGES[this._page].metadata.title || this._page.split("/")[1]}
- - ${dynamicElement(`demo-${this._demo.replace("/", "-")}`)} -