Add the Lit card toolchain and auto-register the Lovelace bundle

This commit is contained in:
2026-09-20 10:08:38 -04:00
parent 7c62c50526
commit edca25affa
17 changed files with 2167 additions and 0 deletions
+1232
View File
File diff suppressed because it is too large Load Diff
+15
View File
@@ -0,0 +1,15 @@
{
"name": "nestquest-cards",
"private": true,
"type": "module",
"scripts": {
"build": "vite build"
},
"dependencies": {
"lit": "^3.3.0"
},
"devDependencies": {
"typescript": "^5.9.2",
"vite": "^7.1.5"
}
}
+35
View File
@@ -0,0 +1,35 @@
import { LitElement, html } from "lit";
import { registerCustomCard, type CardConfig, type HassLike } from "../types";
export class NestQuestAdminCard extends LitElement {
static properties = {
hass: { attribute: false },
_config: { state: true },
};
hass?: HassLike;
_config?: CardConfig;
setConfig(config: CardConfig): void {
if (!config || typeof config !== "object") {
throw new Error("Invalid configuration");
}
this._config = config;
}
getCardSize(): number {
return 8;
}
render() {
return html`<div>NestQuest Admin</div>`;
}
}
customElements.define("nestquest-admin-card", NestQuestAdminCard);
registerCustomCard({
type: "nestquest-admin-card",
name: "NestQuest Admin",
description: "Parent phone view for today, tasks, schedule, and history.",
});
+35
View File
@@ -0,0 +1,35 @@
import { LitElement, html } from "lit";
import { registerCustomCard, type CardConfig, type HassLike } from "../types";
export class NestQuestPartyBoardCard extends LitElement {
static properties = {
hass: { attribute: false },
_config: { state: true },
};
hass?: HassLike;
_config?: CardConfig;
setConfig(config: CardConfig): void {
if (!config || typeof config !== "object") {
throw new Error("Invalid configuration");
}
this._config = config;
}
getCardSize(): number {
return 6;
}
render() {
return html`<div>NestQuest Party Board</div>`;
}
}
customElements.define("nestquest-party-board-card", NestQuestPartyBoardCard);
registerCustomCard({
type: "nestquest-party-board-card",
name: "NestQuest Party Board",
description: "Kids' attract screen for present and away adventurers.",
});
+35
View File
@@ -0,0 +1,35 @@
import { LitElement, html } from "lit";
import { registerCustomCard, type CardConfig, type HassLike } from "../types";
export class NestQuestQuestLogCard extends LitElement {
static properties = {
hass: { attribute: false },
_config: { state: true },
};
hass?: HassLike;
_config?: CardConfig;
setConfig(config: CardConfig): void {
if (!config || typeof config !== "object") {
throw new Error("Invalid configuration");
}
this._config = config;
}
getCardSize(): number {
return 8;
}
render() {
return html`<div>NestQuest Quest Log</div>`;
}
}
customElements.define("nestquest-quest-log-card", NestQuestQuestLogCard);
registerCustomCard({
type: "nestquest-quest-log-card",
name: "NestQuest Quest Log",
description: "One child's daily quests, grouped by window.",
});
+3
View File
@@ -0,0 +1,3 @@
import "./cards/party-board";
import "./cards/quest-log";
import "./cards/admin";
+20
View File
@@ -0,0 +1,20 @@
export type HassLike = Record<string, unknown>;
export type CardConfig = Record<string, unknown>;
export type CustomCardInfo = {
type: string;
name: string;
description: string;
};
declare global {
interface Window {
customCards?: CustomCardInfo[];
}
}
export function registerCustomCard(info: CustomCardInfo): void {
window.customCards = window.customCards ?? [];
window.customCards.push(info);
}
+13
View File
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"lib": ["ES2022", "DOM"],
"strict": true,
"skipLibCheck": true,
"noEmit": true,
"isolatedModules": true
},
"include": ["src"]
}
+19
View File
@@ -0,0 +1,19 @@
import { defineConfig } from "vite";
export default defineConfig({
build: {
outDir: "../custom_components/nestquest/www",
emptyOutDir: false,
sourcemap: false,
lib: {
entry: "src/nestquest-cards.ts",
formats: ["es"],
fileName: () => "nestquest-cards.js",
},
rollupOptions: {
output: {
inlineDynamicImports: true,
},
},
},
});