diff --git a/public/demo/layout.yaml b/public/demo/layout.yaml index eade03e..1abe832 100644 --- a/public/demo/layout.yaml +++ b/public/demo/layout.yaml @@ -402,3 +402,24 @@ children: - type: el text: Landscape showForOrientation: landscape + - showForNav: /layout/layout + children: + - type: md + content: | + To use Home Assistant cards with LCARS, you need to use the `ha-lcars-layout` + layout. You can then add any home assistant card using the `ha-card` type. + + ``` + views: + - path: api + title: LCARS + type: custom:ha-lcars-layout + cards: + - show_name: true + show_icon: true + type: button + entity: input_boolean.test_boolean_1 + children: + - type: ha-card + cardIndex: 0 + ``` diff --git a/src/ComponentRegistry.ts b/src/ComponentRegistry.ts index 6bdc759..92597d9 100644 --- a/src/ComponentRegistry.ts +++ b/src/ComponentRegistry.ts @@ -2,6 +2,7 @@ import AbsoluteContainer from './components/AbsoluteContainer.vue' import AttributeFlow from './components/AttributeFlow.vue' import AttributeList from './components/AttributeList.vue' import AttributeTable from './components/AttributeTable.vue' +import HACard from './components/HACard.vue' import LCARSApi from './components/LCARSApi.vue' import LCARSCol from './components/LCARSCol.vue' import LCARSElement from './components/LCARSElement.vue' @@ -39,6 +40,7 @@ export function registerAllComponents() { registerComponent('attribute-list', AttributeList) registerComponent('col', LCARSCol) registerComponent('el', LCARSElement) + registerComponent('ha-card', HACard) registerComponent('modal', LCARSModal) registerComponent('md', LCARSMarkdown) registerComponent('menu-horizontal', MenuHorizontal) diff --git a/src/HAConfig.ts b/src/HAConfig.ts index bf6eaad..e16c1a6 100644 --- a/src/HAConfig.ts +++ b/src/HAConfig.ts @@ -23,6 +23,8 @@ export const haConfig = ref({ children: [], } as HAConfig) +export const haCards = ref>([]) + export const mixins = ref({} as any) export function loadConfig(config: any) { diff --git a/src/LCARSCustomLayout.ts b/src/LCARSCustomLayout.ts new file mode 100644 index 0000000..7f512a1 --- /dev/null +++ b/src/LCARSCustomLayout.ts @@ -0,0 +1,106 @@ +import { haState } from './HAState' +import { haCards, haConfig, loadConfig } from './HAConfig' +import './editor.ts' + +export class LCARSCustomLayout extends HTMLElement { + private vueElement: any + private test: boolean = false + + static get observedAttributes() { + return ['config', 'test'] + } + + static get properties() { + return { + cards: { type: Array, attribute: false }, + } + } + + constructor() { + super() + this.attachShadow({ mode: 'open' }) + this.vueElement = null + } + + set loadTest(test: any) { + this.setLoadTest(test) + } + + setLoadTest(test: any) { + this.test = test + if (this.vueElement) { + this.vueElement.loadTest = test + } + } + + set config(config: any) { + this.setConfig(config) + } + + set panel(panel: any) { + if (panel.config) { + this.setConfig(panel.config) + } + } + + set hass(hass: any) { + haState.value = hass + } + + set cards(cards: Array) { + haCards.value = cards + console.log(cards) + } + + setConfig(config: any) { + loadConfig(config) + + if (this.vueElement) { + this.vueElement.config = config + } + } + + attributeChangedCallback(name: string, oldValue: any, newValue: any) { + if (name === 'test') { + this.loadTest = true + } + if (name === 'config') { + this.setConfig(newValue) + } + } + + connectedCallback() { + if (!this.vueElement) { + this.vueElement = document.createElement('lcars-card') + this.vueElement.config = haConfig.value ?? { children: [] } + this.vueElement.loadTest = this.test + this.shadowRoot?.appendChild(this.vueElement) + + const head = document.head + const link = document.createElement('link') + + link.type = 'text/css' + link.rel = 'stylesheet' + link.href = 'https://fonts.googleapis.com/css2?family=Antonio:wght@400;700&display=swap' + + head.appendChild(link) + + // watch(haConfig, (newConfig) => { + // this.setConfig(newConfig) + // const event = new Event('config-changed', { + // bubbles: true, + // composed: true, + // }) as any + // event.detail = { config: newConfig } + // this.dispatchEvent(event) + // }) + } + } + + disconnectedCallback() { + if (this.vueElement) { + this.shadowRoot?.removeChild(this.vueElement) + this.vueElement = null + } + } +} diff --git a/src/assets/config/demo.yaml b/src/assets/config/demo.yaml index cabc8a7..4c51f13 100644 --- a/src/assets/config/demo.yaml +++ b/src/assets/config/demo.yaml @@ -22,6 +22,7 @@ nav: - text: Alignment - text: Spacing - text: Orientation + - text: Layout - text: Elements children: - text: Element diff --git a/src/components/HACard.vue b/src/components/HACard.vue new file mode 100644 index 0000000..1f5a924 --- /dev/null +++ b/src/components/HACard.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/main.ts b/src/main.ts index 70fb473..8e3837c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,6 +3,7 @@ import LCARSCardCe from './LCARSCard.ce.vue' import { LCARSCustomCard } from './LCARSCustomCard.ts' import { registerAllComponents } from './ComponentRegistry.ts' import './editor.ts' +import { LCARSCustomLayout } from './LCARSCustomLayout.ts' customElements.define('lcars-card', defineCustomElement(LCARSCardCe)) ;(window as any).customCards = (window as any).customCards || [] @@ -20,4 +21,8 @@ if (!customElements.get('ha-lcars-panel')) { customElements.define('ha-lcars-panel', LCARSCustomCard) } +if (!customElements.get('ha-lcars-layout')) { + customElements.define('ha-lcars-layout', LCARSCustomLayout) +} + registerAllComponents()