Appearance
Architecture
BetoDashboard is built on a few simple, powerful concepts that prioritize performance, type-safety, and developer experience without relying on a heavy framework.
Core Principles
- Zero Dependencies: The core reactive system and component engine are written in plain TypeScript with no external runtime libraries.
- Declarative HTML: Components are declared directly in your HTML, making the structure easy to understand and server-render.
- Centralized State: A single global store manages application state, providing a predictable data flow.
Global Store
The global store (src/js/store.ts) is the single source of truth for shared application state. It's a lightweight, reactive object that allows components to read state and subscribe to changes.
Design
- Technology: A custom pub/sub system built on a
Map. - Reactivity: When state is updated with
store.set(), only the listeners subscribed to that specific key are notified. - Persistence: Certain UI-related keys (like
themeandsidebar) are automatically persisted tolocalStorage.
API
store.get(key): Retrieves the current value for a state key.store.set(key, value): Updates a key's value and notifies all its subscribers.store.on(key, listener): Subscribes a function to changes for a specific key. Returns anunsubscribefunction.
Example Usage
typescript
import { store } from './js/store';
// 1. Subscribe to changes for the 'theme' key
const unsubscribe = store.on('theme', newTheme => {
console.log(`Theme changed to: ${newTheme}`);
});
// 2. Update the theme
store.set('theme', 'dark'); // "Theme changed to: dark"Dynamic Component Engine (DCE)
The DCE (src/components/runtime.ts) is a tiny runtime that discovers and mounts components declared in your HTML. It allows for a declarative, low-JavaScript approach to building interactive UIs.
How It Works
- Declaration: You declare a component in HTML using a
data-componentattribute. - Props & Slots: Props are passed as a JSON string in
data-props, and named slots are defined using<template data-slot="...">. - Mounting: On page load,
mountAll()finds all[data-component]elements, parses their props and slots, and runs the corresponding component constructor function.
Example Usage
HTML:
html
<div
data-component="Table"
data-props='{"columns": [{"key": "name", "label": "Name"}]}'
>
<template data-slot="empty"><p>No data available.</p></template>
</div>Prev: Getting Started | Next: API Fetching
See also: Docs Index | Project README