mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-13 20:36:35 +00:00
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
This commit is contained in:
parent
76a4b1efbd
commit
e3d78d6dc5
@ -25,7 +25,7 @@ gulp.task("gather-gallery-demos", async function gatherDemos() {
|
|||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const demoId = path.basename(file, ".ts");
|
const demoId = path.basename(file, ".ts");
|
||||||
const demoPath = "../src/demos/" + demoId;
|
const demoPath = "../src/demos/" + demoId;
|
||||||
content += ` "${demoId}": () => import("${demoPath}"),\n`;
|
content += ` "${demoId.substring(5)}": () => import("${demoPath}"),\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
content += "};";
|
content += "};";
|
||||||
|
@ -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`
|
|
||||||
<style>
|
|
||||||
.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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<h2>
|
|
||||||
[[config.heading]]
|
|
||||||
<template is="dom-if" if="[[_size]]">
|
|
||||||
<small>(size [[_size]])</small>
|
|
||||||
</template>
|
|
||||||
</h2>
|
|
||||||
<div class="root">
|
|
||||||
<div id="card"></div>
|
|
||||||
<template is="dom-if" if="[[showConfig]]">
|
|
||||||
<pre>[[_trim(config.config)]]</pre>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
129
gallery/src/components/demo-card.ts
Normal file
129
gallery/src/components/demo-card.ts
Normal file
@ -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`
|
||||||
|
<h2>
|
||||||
|
${this.config.heading}
|
||||||
|
${this._size !== undefined
|
||||||
|
? html`<small>(size ${this._size})</small>`
|
||||||
|
: ""}
|
||||||
|
</h2>
|
||||||
|
<div class="root">
|
||||||
|
<div id="card"></div>
|
||||||
|
${this.showConfig ? html`<pre>${this.config.config.trim()}</pre>` : ""}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -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`
|
|
||||||
<style>
|
|
||||||
#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;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<app-toolbar>
|
|
||||||
<div class="filters">
|
|
||||||
<ha-formfield label="Show config">
|
|
||||||
<ha-switch checked="[[_showConfig]]" on-change="_showConfigToggled">
|
|
||||||
</ha-switch>
|
|
||||||
</ha-formfield>
|
|
||||||
<ha-formfield label="Dark theme">
|
|
||||||
<ha-switch on-change="_darkThemeToggled"> </ha-switch>
|
|
||||||
</ha-formfield>
|
|
||||||
</div>
|
|
||||||
</app-toolbar>
|
|
||||||
<div id="container">
|
|
||||||
<div class="cards">
|
|
||||||
<template is="dom-repeat" items="[[configs]]">
|
|
||||||
<demo-card
|
|
||||||
config="[[item]]"
|
|
||||||
show-config="[[_showConfig]]"
|
|
||||||
hass="[[hass]]"
|
|
||||||
></demo-card>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
92
gallery/src/components/demo-cards.ts
Normal file
92
gallery/src/components/demo-cards.ts
Normal file
@ -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`
|
||||||
|
<app-toolbar>
|
||||||
|
<div class="filters">
|
||||||
|
<ha-formfield label="Show config">
|
||||||
|
<ha-switch
|
||||||
|
.checked=${this._showConfig}
|
||||||
|
@change=${this._showConfigToggled}
|
||||||
|
>
|
||||||
|
</ha-switch>
|
||||||
|
</ha-formfield>
|
||||||
|
<ha-formfield label="Dark theme">
|
||||||
|
<ha-switch @change=${this._darkThemeToggled}> </ha-switch>
|
||||||
|
</ha-formfield>
|
||||||
|
</div>
|
||||||
|
</app-toolbar>
|
||||||
|
<div id="container">
|
||||||
|
<div class="cards">
|
||||||
|
${this.configs.map(
|
||||||
|
(config) => html`
|
||||||
|
<demo-card
|
||||||
|
.config=${config}
|
||||||
|
.showConfig=${this._showConfig}
|
||||||
|
.hass=${this.hass}
|
||||||
|
></demo-card>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
_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;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import { html, LitElement, TemplateResult } from "lit";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
import { customElement } from "lit/decorators";
|
import { customElement, query } from "lit/decorators";
|
||||||
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
@ -38,9 +39,16 @@ const CONFIGS = [
|
|||||||
|
|
||||||
@customElement("demo-hui-iframe-card")
|
@customElement("demo-hui-iframe-card")
|
||||||
class DemoIframe extends LitElement {
|
class DemoIframe extends LitElement {
|
||||||
|
@query("demo-cards") private _demos!: HTMLElement;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
return html`<demo-cards id="demos" .configs=${CONFIGS}></demo-cards>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
|
super.firstUpdated(changedProperties);
|
||||||
|
provideHass(this._demos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -73,6 +73,6 @@ class DemoHuiMediaPlayerRow extends LitElement {
|
|||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
"demo-hui-media-player-row": DemoHuiMediaPlayerRow;
|
"demo-hui-media-player-rows": DemoHuiMediaPlayerRow;
|
||||||
}
|
}
|
||||||
}
|
}
|
43
gallery/src/demos/demo-introduction.ts
Normal file
43
gallery/src/demos/demo-introduction.ts
Normal file
@ -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`
|
||||||
|
<ha-card header="Welcome!">
|
||||||
|
<div class="card-content">
|
||||||
|
<ha-markdown
|
||||||
|
.content=${`
|
||||||
|
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.
|
||||||
|
`}
|
||||||
|
></ha-markdown>
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return css`
|
||||||
|
ha-card {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 24px auto;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-introduction": DemoIntroduction;
|
||||||
|
}
|
||||||
|
}
|
@ -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`
|
|
||||||
<style include="iron-positioning ha-style">
|
|
||||||
:host {
|
|
||||||
-ms-user-select: initial;
|
|
||||||
-webkit-user-select: initial;
|
|
||||||
-moz-user-select: initial;
|
|
||||||
}
|
|
||||||
app-header-layout {
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
ha-icon-button.invisible {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pickers {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pickers ha-card {
|
|
||||||
width: 400px;
|
|
||||||
display: block;
|
|
||||||
margin: 16px 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pickers ha-card:last-child {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.intro {
|
|
||||||
margin: -1em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p a {
|
|
||||||
color: var(--primary-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<app-header-layout>
|
|
||||||
<app-header slot="header" fixed>
|
|
||||||
<app-toolbar>
|
|
||||||
<ha-icon-button
|
|
||||||
on-click="_backTapped"
|
|
||||||
class$="[[_computeHeaderButtonClass(_demo)]]"
|
|
||||||
>
|
|
||||||
<ha-icon icon="hass:arrow-left"></ha-icon>
|
|
||||||
</ha-icon-button>
|
|
||||||
<div main-title>
|
|
||||||
[[_withDefault(_demo, "Home Assistant Gallery")]]
|
|
||||||
</div>
|
|
||||||
</app-toolbar>
|
|
||||||
</app-header>
|
|
||||||
|
|
||||||
<div class="content">
|
|
||||||
<div id="demo"></div>
|
|
||||||
<template is="dom-if" if="[[!_demo]]">
|
|
||||||
<div class="pickers">
|
|
||||||
<ha-card header="Lovelace Card Demos">
|
|
||||||
<div class="card-content intro">
|
|
||||||
<p>
|
|
||||||
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.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This gallery helps our developers and designers to see all
|
|
||||||
the different states that each card can be in.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Check
|
|
||||||
<a href="https://www.home-assistant.io/lovelace"
|
|
||||||
>the official website</a
|
|
||||||
>
|
|
||||||
for instructions on how to get started with Lovelace.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<template is="dom-repeat" items="[[_lovelaceDemos]]">
|
|
||||||
<a href="#[[item]]">
|
|
||||||
<paper-item>
|
|
||||||
<paper-item-body>{{ item }}</paper-item-body>
|
|
||||||
<ha-icon icon="hass:chevron-right"></ha-icon>
|
|
||||||
</paper-item>
|
|
||||||
</a>
|
|
||||||
</template>
|
|
||||||
</ha-card>
|
|
||||||
|
|
||||||
<ha-card header="Other Demos">
|
|
||||||
<div class="card-content intro"></div>
|
|
||||||
<template is="dom-repeat" items="[[_restDemos]]">
|
|
||||||
<a href="#[[item]]">
|
|
||||||
<paper-item>
|
|
||||||
<paper-item-body>{{ item }}</paper-item-body>
|
|
||||||
<ha-icon icon="hass:chevron-right"></ha-icon>
|
|
||||||
</paper-item>
|
|
||||||
</a>
|
|
||||||
</template>
|
|
||||||
</ha-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</app-header-layout>
|
|
||||||
<notification-manager
|
|
||||||
hass="[[_fakeHass]]"
|
|
||||||
id="notifications"
|
|
||||||
></notification-manager>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
207
gallery/src/ha-gallery.ts
Normal file
207
gallery/src/ha-gallery.ts
Normal file
@ -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`
|
||||||
|
<mwc-drawer open hasHeader type="dismissible">
|
||||||
|
<span slot="title">Home Assistant Design</span>
|
||||||
|
<!-- <span slot="subtitle">subtitle</span> -->
|
||||||
|
<div class="sidebar">
|
||||||
|
${DEMOS_GROUPED.map(
|
||||||
|
(group) => html`
|
||||||
|
${group.header
|
||||||
|
? html`<p class="section">${group.header}</p>`
|
||||||
|
: ""}
|
||||||
|
${group.demos!.map((demo) =>
|
||||||
|
this._renderDemo(demo, group.demoStart)
|
||||||
|
)}
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div slot="appContent">
|
||||||
|
<mwc-top-app-bar-fixed>
|
||||||
|
<ha-icon-button
|
||||||
|
slot="navigationIcon"
|
||||||
|
@click=${this._menuTapped}
|
||||||
|
.path=${mdiMenu}
|
||||||
|
></ha-icon-button>
|
||||||
|
|
||||||
|
<div slot="title">${this._demo}</div>
|
||||||
|
</mwc-top-app-bar-fixed>
|
||||||
|
<div>${dynamicElement(`demo-${this._demo}`)}</div>
|
||||||
|
</div>
|
||||||
|
</mwc-drawer>
|
||||||
|
<notification-manager
|
||||||
|
.hass=${FAKE_HASS}
|
||||||
|
id="notifications"
|
||||||
|
></notification-manager>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _renderDemo(demo: string, demoStart?: string) {
|
||||||
|
return html`
|
||||||
|
<a ?active=${this._demo === demo} href=${`#${demo}`}
|
||||||
|
>${demoStart === undefined ? demo : demo.substring(demoStart.length)}</a
|
||||||
|
>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -52,6 +52,7 @@
|
|||||||
"@material/mwc-checkbox": "0.25.3",
|
"@material/mwc-checkbox": "0.25.3",
|
||||||
"@material/mwc-circular-progress": "0.25.3",
|
"@material/mwc-circular-progress": "0.25.3",
|
||||||
"@material/mwc-dialog": "0.25.3",
|
"@material/mwc-dialog": "0.25.3",
|
||||||
|
"@material/mwc-drawer": "^0.25.3",
|
||||||
"@material/mwc-fab": "0.25.3",
|
"@material/mwc-fab": "0.25.3",
|
||||||
"@material/mwc-formfield": "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",
|
"@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": "0.25.3",
|
||||||
"@material/mwc-tab-bar": "0.25.3",
|
"@material/mwc-tab-bar": "0.25.3",
|
||||||
"@material/mwc-textfield": "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",
|
"@material/top-app-bar": "14.0.0-canary.261f2db59.0",
|
||||||
"@mdi/js": "6.5.95",
|
"@mdi/js": "6.5.95",
|
||||||
"@mdi/svg": "6.5.95",
|
"@mdi/svg": "6.5.95",
|
||||||
|
@ -92,6 +92,10 @@ class NotificationManager extends LitElement {
|
|||||||
customElements.define("notification-manager", NotificationManager);
|
customElements.define("notification-manager", NotificationManager);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"notification-manager": NotificationManager;
|
||||||
|
}
|
||||||
|
|
||||||
// for fire event
|
// for fire event
|
||||||
interface HASSDomEvents {
|
interface HASSDomEvents {
|
||||||
"hass-notification": ShowToastParams;
|
"hass-notification": ShowToastParams;
|
||||||
|
62
yarn.lock
62
yarn.lock
@ -2126,6 +2126,26 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
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":
|
"@material/elevation@npm:14.0.0-canary.261f2db59.0":
|
||||||
version: 14.0.0-canary.261f2db59.0
|
version: 14.0.0-canary.261f2db59.0
|
||||||
resolution: "@material/elevation@npm:14.0.0-canary.261f2db59.0"
|
resolution: "@material/elevation@npm:14.0.0-canary.261f2db59.0"
|
||||||
@ -2343,6 +2363,20 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
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":
|
"@material/mwc-fab@npm:0.25.3":
|
||||||
version: 0.25.3
|
version: 0.25.3
|
||||||
resolution: "@material/mwc-fab@npm:0.25.3"
|
resolution: "@material/mwc-fab@npm:0.25.3"
|
||||||
@ -2624,6 +2658,30 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
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":
|
"@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
|
version: 14.0.0-canary.261f2db59.0
|
||||||
resolution: "@material/notched-outline@npm:14.0.0-canary.261f2db59.0"
|
resolution: "@material/notched-outline@npm:14.0.0-canary.261f2db59.0"
|
||||||
@ -2869,7 +2927,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
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
|
version: 14.0.0-canary.261f2db59.0
|
||||||
resolution: "@material/top-app-bar@npm:14.0.0-canary.261f2db59.0"
|
resolution: "@material/top-app-bar@npm:14.0.0-canary.261f2db59.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -9022,6 +9080,7 @@ fsevents@^1.2.7:
|
|||||||
"@material/mwc-checkbox": 0.25.3
|
"@material/mwc-checkbox": 0.25.3
|
||||||
"@material/mwc-circular-progress": 0.25.3
|
"@material/mwc-circular-progress": 0.25.3
|
||||||
"@material/mwc-dialog": 0.25.3
|
"@material/mwc-dialog": 0.25.3
|
||||||
|
"@material/mwc-drawer": ^0.25.3
|
||||||
"@material/mwc-fab": 0.25.3
|
"@material/mwc-fab": 0.25.3
|
||||||
"@material/mwc-formfield": 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"
|
"@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": 0.25.3
|
||||||
"@material/mwc-tab-bar": 0.25.3
|
"@material/mwc-tab-bar": 0.25.3
|
||||||
"@material/mwc-textfield": 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
|
"@material/top-app-bar": 14.0.0-canary.261f2db59.0
|
||||||
"@mdi/js": 6.5.95
|
"@mdi/js": 6.5.95
|
||||||
"@mdi/svg": 6.5.95
|
"@mdi/svg": 6.5.95
|
||||||
|
Loading…
x
Reference in New Issue
Block a user