Barebones, working HTML/CSS components for building dashboard applications — with dual package builds (Web Components + Angular).
Style first in Storybook. Ship via npm run build.
Source of truth: components/<name>/<name>.html + <name>.css. Generators produce Custom Elements and Angular standalone wrappers. Headless Angular primitives live under src/angular/headless/.
npm install
npm run sync # regenerate CSS barrel, CE/Angular, stories
npm run storybook # design browser → http://localhost:6006
npm run dev # curated reference site → http://localhost:3000
npm run build # styles + WC + html pack + Angular → dist/Editing components/** hot-updates Storybook. Adding/removing a folder regenerates stories and wrappers.
| Feature | Where |
|---|---|
| Canvas | Live component preview |
| Docs | Autodocs + packaged HTML source (.demo fragment) |
| Theme | Toolbar — light / dark (data-theme) |
| Viewport | Toolbar — phone, tablet, desktop, deml widths |
| Backgrounds | Toolbar — page / surface / charcoal |
| Measure / Outline | Toolbar — spacing & box inspection |
| Density | Toolbar — compact / comfortable / spacious |
| A11y | Panel — axe (WCAG 2 A/AA + best practices) |
| Actions | Panel — click / submit / change / input |
- Dashboard — composition example
- Shell — app chrome, page headers, navigation
- Layout — stack, grid, panels, spacing recipes
- Forms — fields, inputs, buttons, switches
- Feedback — badges, callouts, toasts, loaders
- Data — cards, metrics, tables, charts
- Overlays — dialogs, sheets, tabs, menus
npm run storybook # this UI
npm run build # styles + web components + Angular → dist/
npm run build-storybook # static site| Command | Purpose |
|---|---|
npm run sync |
CSS barrel + CE/Angular wrappers + Storybook stories |
npm run storybook |
Sync + Storybook dev |
npm run build-storybook |
Static Storybook → storybook-static/ |
npm run build |
Full library package → dist/ |
npm run dev |
Vite reference site |
Custom elements use the deml-* tag prefix (e.g. <deml-button>).
components/<name>/ # SOURCE OF TRUTH — style here
styles/tokens.css # design tokens
styles/library.css # package CSS entry
src/web-components/ # CE browser entry
src/angular/ # Angular public API (markup + headless)
src/angular/headless/ # Headless primitives (hand-authored)
generated/ # AUTO: CE + Angular markup wrappers (re-run sync)
stories/ # Introduction + Dashboard MDX; *.stories.js auto
scripts/ # generators + build
.storybook/ # Storybook 10 (HTML + Vite)
- Create
components/<name>/<name>.htmland<name>.css - Put reusable markup inside
.demo(section chrome is Storybook-only) - Add the name to the right group in
scripts/lib/components.mjs→CATEGORIES - Run
npm run sync - Optional
meta.json:{ "package": true, "tag": "deml-my-thing" }
Style BEM roots (.card, .button, .tabs, …) — not only .component--name.
Packaged tags are deml-<name> (e.g. deml-button).
Unstyled, accessible primitives with Signals — behavior only, you own CSS.
Composition-first (root + parts). Shared models: [(open)] / [(value)], (change), (opened) / (closed), data-state.
| Primitive | Import | Parts |
|---|---|---|
| Tabs | DEML_TABS_IMPORTS |
demlTabList, demlTab, demlTabPanel |
| Dialog | DEML_DIALOG_IMPORTS |
panel / title / description / close |
| Disclosure | DEML_DISCLOSURE_IMPORTS |
button / panel |
| Combobox | DEML_COMBOBOX_IMPORTS |
label / input / button / options |
| Menu | DEML_MENU_IMPORTS |
button / items / item |
import { DEML_COMBOBOX_IMPORTS } from "deml-ui/angular";See USAGE.md and CONVENTIONS.md.
Curated for app/dashboard composition — not an HTML element encyclopedia.
| Group | Examples |
|---|---|
| Shell | app-layout, app-header, app-sidebar, page-header, sidebar-nav, breadcrumbs |
| Layout | stack, grid, panel-grid, form-grid, section, container, split-panel |
| Forms | field, button, input-*, select, checkbox, radio-group, switch, file-upload |
| Feedback | badge, callout, toast, empty-state, skeleton, spinner |
| Data | card, metric-card, table, chart-panel, pagination, activity-list |
| Overlays | dialog, sheet, tabs, accordion, dropdown, command, wizard |
form-field is shared CSS only (not packaged as a custom element).
import "deml-ui/styles.css";
import "deml-ui"; // defineAll()import { DemlButton } from "deml-ui/angular";<deml-button></deml-button>Peer deps: @angular/core / @angular/common ≥ 19 (optional for WC-only).
- Open Storybook → pick a component
- Edit
components/<name>/<name>.css(structure is already visible) - Use Theme / Viewport / A11y panels
- Compose pages from Shell + Layout + Data primitives
npm run buildwhen ready
Tokens: styles/tokens.css. Prefer token variables (--space-*, --line, --surface) over raw hex in component CSS.
- CI:
npm ci→sync→build→build-storybook - Vercel: Storybook static (
build-storybook→storybook-static)
ISC