Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions public/demo/layout.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
2 changes: 2 additions & 0 deletions src/ComponentRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions src/HAConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export const haConfig = ref<HAConfig>({
children: [],
} as HAConfig)

export const haCards = ref<Array<any>>([])

export const mixins = ref({} as any)

export function loadConfig(config: any) {
Expand Down
106 changes: 106 additions & 0 deletions src/LCARSCustomLayout.ts
Original file line number Diff line number Diff line change
@@ -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<any>) {
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
}
}
}
1 change: 1 addition & 0 deletions src/assets/config/demo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ nav:
- text: Alignment
- text: Spacing
- text: Orientation
- text: Layout
- text: Elements
children:
- text: Element
Expand Down
18 changes: 18 additions & 0 deletions src/components/HACard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script setup lang="ts">
import { haCards } from '@/HAConfig'
import { onMounted, ref } from 'vue'

const { cardIndex } = defineProps<{ cardIndex: number }>()

const cardRef = ref()

onMounted(() => {
if (cardIndex < haCards.value?.length) {
cardRef.value.appendChild(haCards.value[cardIndex])
}
})
</script>

<template>
<div ref="cardRef"></div>
</template>
5 changes: 5 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 || []
Expand All @@ -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()
Loading