Skip to content

Commit fa024b6

Browse files
authored
feat: add basic theme support (#64)
1 parent 48be25a commit fa024b6

File tree

8 files changed

+145
-2
lines changed

8 files changed

+145
-2
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,4 @@ If you'd prefer to jump right in, you can find sample configurations (including
4747
which provided the list of available colors.
4848
- Thanks to [LCARS Anomations](https://youtube.com/playlist?list=PLah0JzbIlDe8vDgRiKqmX7yTxDFh4yEYA&si=UuGOlyX1Z4b-LT1n)
4949
on YouTube for inspiration for components and demos.
50+
- Thanks to [The LCARS](https://www.thelcars.com/) for coming up with some cool themes that are supported here.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ha-lcars-panel",
3-
"version": "0.0.11",
3+
"version": "0.0.12",
44
"license": "MIT",
55
"type": "module",
66
"scripts": {

src/HAConfig.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,18 @@ import LCARSMarkdown from './components/LCARSMarkdown.vue'
1818
import type { ConfigItem } from './ConfigItem'
1919
import { ref } from 'vue'
2020
import LCARSSample from './components/LCARSSample.vue'
21+
import LCARSThemeSample from './components/LCARSThemeSample.vue'
2122
import StateValueTable from './components/StateValueTable.vue'
23+
import themeConfig from '@/assets/themes/themes.yaml?raw'
24+
import YAML from 'yaml'
2225

2326
export interface HAConfig {
2427
type: string
2528
vars: Record<string, string>
2629
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2730
mixins: Record<string, any>
2831
children: ConfigItem[]
32+
theme?: string
2933
}
3034

3135
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -46,6 +50,7 @@ registerComponent('panel-all', PanelAll)
4650
registerComponent('table', LCARSTable)
4751
registerComponent('md', LCARSMarkdown)
4852
registerComponent('sample', LCARSSample)
53+
registerComponent('theme-sample', LCARSThemeSample)
4954
registerComponent('state-color', StateColor)
5055
registerComponent('state-value', StateValue)
5156
registerComponent('state-value-table', StateValueTable)
@@ -72,6 +77,15 @@ export function loadVariables(haConfig: HAConfig) {
7277
}
7378
}
7479

80+
export function loadTheme(theme: string) {
81+
const themes = YAML.parse(themeConfig)
82+
const colors = themes[theme]
83+
for (let i = 0; i < 10; i++) {
84+
const index = i % colors.length
85+
setVariable(`lcars-color-${i + 1}`, `var(--lcars-color-${colors[index] as string})`)
86+
}
87+
}
88+
7589
export function loadMixins(haConfig: HAConfig) {
7690
if (haConfig?.mixins) {
7791
mixins.value = haConfig.mixins

src/LCARSCard.ce.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script setup lang="ts">
22
import { computed, onMounted } from 'vue'
33
import type { HAConfig } from './HAConfig'
4-
import { loadMixins, loadVariables } from './HAConfig'
4+
import { loadMixins, loadTheme, loadVariables } from './HAConfig'
55
import RecursiveComponent from './components/RecursiveComponent.vue'
66
import testConfig from '@/assets/config/demo.yaml?raw'
77
import YAML from 'yaml'
@@ -46,6 +46,11 @@ function addCssLink(href: string) {
4646
4747
onMounted(() => {
4848
loadVariables(testConfigParsed ?? config)
49+
if (config.theme) {
50+
loadTheme(config.theme)
51+
} else {
52+
loadTheme('default')
53+
}
4954
const cssRoot = getCssRoot()
5055
if (cssRoot) {
5156
addCssLink(`${cssRoot}ha-lcars-panel.css`)

src/assets/config/demo.yaml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ children:
5858
text: Actions
5959
color: dodger-blue
6060
textColor: black
61+
- type: el
62+
nav: /demo/themes
63+
text: Themes
64+
color: indian-red
65+
textColor: black
6166
children:
6267
- showForNav: /home
6368
children:
@@ -1050,3 +1055,21 @@ children:
10501055
service: light.turn_on
10511056
data:
10521057
entity_id: light.my_light
1058+
1059+
- showForNav: /demo/themes
1060+
children:
1061+
- type: sample
1062+
content: |
1063+
You can select a theme by setting the `theme` top-level config key.
1064+
1065+
Themes provide 10 numbered colors that can be set by simply specifying the number 1-10. You can create
1066+
your own custom theme by using the `vars` top-level configuration key to set the values of variables
1067+
`lcars-color-1` through `lcars-color-10` to any valid CSS color.
1068+
1069+
Supported themes are shown below.
1070+
configYaml: |
1071+
- type: pill
1072+
color: 1
1073+
text: Color 1
1074+
width: 4
1075+
- type: theme-sample

src/assets/themes/themes.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
default:
2+
- mauve #c9f
3+
- flushed-mahogany #c44
4+
- pizazz #f80
5+
- atomic-tangerine #f96
6+
- malibu #89f
7+
- wax-flower #fba
8+
- heliotrope #96f
9+
nemesis:
10+
- tan #ca8
11+
- zircon #ebf0ff
12+
- blue-ribbon #26f
13+
- malibu #69f
14+
- crusta #f83
15+
- peach-orange #fc9
16+
- blue #23f
17+
- comet #52526a
18+
lower-decks:
19+
- vermilion #f40
20+
- flush-orange #f70
21+
- peach-orange #fc9
22+
- yellow-orange #fa4
23+
- west-side #f91
24+
lower-decks-padd:
25+
- cornflower-blue #58e
26+
- anakiwa #8ff
27+
- danube #79d
28+
- malibu #6cf
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<script setup lang="ts">
2+
import { computed, ref } from 'vue'
3+
import YAML from 'yaml'
4+
import themeConfig from '@/assets/themes/themes.yaml?raw'
5+
import LCARSElement from './LCARSElement.vue'
6+
import PanelTL from './PanelTL.vue'
7+
import LCARSCol from './LCARSCol.vue'
8+
9+
const selectedTheme = ref<string>('default')
10+
11+
const parsedConfig = computed(() => {
12+
if (!themeConfig) {
13+
return {}
14+
}
15+
16+
return YAML.parse(themeConfig)
17+
})
18+
19+
const themeNames = computed(() => {
20+
const themes = parsedConfig.value
21+
if (!themes) {
22+
return []
23+
}
24+
return Object.keys(themes)
25+
})
26+
27+
const theme = computed(() => {
28+
let colors = []
29+
if (selectedTheme.value) {
30+
const themeConfig = parsedConfig.value[selectedTheme.value]
31+
for (let i = 0; i < 10; i++) {
32+
const index = i % themeConfig.length
33+
colors.push(themeConfig[index])
34+
}
35+
}
36+
return colors as string[]
37+
})
38+
</script>
39+
40+
<template>
41+
<PanelTL :width="1" color="1" :left-width="5">
42+
<template #left>
43+
<LCARSElement
44+
v-for="(name, index) in themeNames"
45+
:key="index"
46+
:color="parsedConfig[name][0] ?? '1'"
47+
:width="5"
48+
text-color="black"
49+
:button="true"
50+
@click="selectedTheme = name"
51+
text-transform="none"
52+
:cap-right="selectedTheme === name"
53+
>{{ name }}</LCARSElement
54+
>
55+
</template>
56+
<LCARSElement
57+
v-if="theme"
58+
v-for="(color, index) in theme"
59+
:key="index"
60+
:color="color"
61+
:width="5"
62+
:pad-left="0.1"
63+
text-color="black"
64+
text-align="center"
65+
>
66+
Color {{ index + 1 }}
67+
</LCARSElement>
68+
</PanelTL>
69+
</template>

src/styles/colors.sass

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@
136136
--lcars-color-blue-haze: #BDBACE
137137
--lcars-color-blue-lagoon: #00626F
138138
--lcars-color-blue-marguerite: #6A5BB1
139+
--lcars-color-blue-ribbon: #0066FF
139140
--lcars-color-blue-romance: #D8F0D2
140141
--lcars-color-blue-smoke: #78857A
141142
--lcars-color-blue-stone: #166461
@@ -547,6 +548,8 @@
547548
--lcars-color-flint: #716E61
548549
--lcars-color-flirt: #7A2E4D
549550
--lcars-color-floral-white: #FFFAF0
551+
--lcars-color-flush-orange: #FF7F00
552+
--lcars-color-flushed-mahogany: #CA3435
550553
--lcars-color-foam: #D0EAE8
551554
--lcars-color-fog: #D5C7E8
552555
--lcars-color-foggy-grey: #A7A69D

0 commit comments

Comments
 (0)