[session 1] docs(guide): frontend-template Rules & Gotchas tab (#36)
CD - Develop (guide → bcos.dev) / build-and-deploy (push) Has started running
CD - Develop (guide → bcos.dev) / build-and-deploy (push) Has started running
This commit was merged in pull request #36.
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
---
|
||||
module: platform.frontend-template
|
||||
title: Frontend Template — starting a new SPA
|
||||
tab: Rules & Gotchas
|
||||
order: 20
|
||||
audience: dev
|
||||
---
|
||||
|
||||
# Design-system rules & hard-won gotchas
|
||||
|
||||
The canonical CSS to **copy verbatim** lives in the template repo's
|
||||
`frontend/src/components/TablePage.svelte` (plain list/table pages) and `TemplatePage.svelte`
|
||||
(pages with severity/status badges) — copy those files, don't rewrite. This tab captures the
|
||||
**rules and gotchas** that aren't obvious from the files.
|
||||
|
||||
## Colors
|
||||
|
||||
| Token | Value | Used for |
|
||||
|-------|-------|----------|
|
||||
| `--color-primary` / `-hover` | `#2563eb` / `#1d4ed8` | buttons, links, active highlights |
|
||||
| `--color-danger` | `#d32f2f` | delete/error |
|
||||
| `--color-success` / `--color-warning` | `#2e7d32` / `#b45309` | badges |
|
||||
| `--color-border` | `#e0e0e0` | card/table borders |
|
||||
| `--color-text-primary` / `-secondary` | `#1a1a1a` / `#666` | body / muted |
|
||||
|
||||
**Sidebar gradient (canonical — do not change per app):**
|
||||
Light `linear-gradient(180deg, #081651 0%, #1c49b8 100%)` · Dark `linear-gradient(180deg, #050e2e 0%, #0f2460 100%)`.
|
||||
(For brand/customer-facing artifacts use the BCOS palette instead — see `platform.branding`. The
|
||||
`#2563eb` above is the app-template blue, not the brand.)
|
||||
|
||||
## Base font size — CRITICAL
|
||||
|
||||
Every app **must** set `font-size: 14px` on `html, body`. All `rem` values are relative to it;
|
||||
omit it and the browser defaults to 16px → every nav item, cell, and badge is ~14% too large.
|
||||
|
||||
```css
|
||||
:global(html), :global(body) { font-size: 14px; } /* required — do not omit */
|
||||
```
|
||||
|
||||
Typography scale (relative to 14px): page-title `1.4rem` · section-title `1.1rem` · body `0.95rem` ·
|
||||
body-sm `0.9rem` · **label `0.85rem` (table cells, form labels)** · caption `0.8rem` · tiny `0.75rem`
|
||||
(uppercase table headers) · subtitle `0.85rem` (`.header p`) · icon `1.1rem` · stat-value `2rem`.
|
||||
|
||||
## CSS isolation — four rules (these burned real hours)
|
||||
|
||||
1. **Use Svelte `<style>` blocks, never a globally imported `.css` file.** Svelte scopes them
|
||||
(`td.svelte-abc123`) so they can't bleed. Dark mode still needs `:global(.dark-mode) .x { … }`
|
||||
*inside* the `<style>` block.
|
||||
2. **If a global `.css` is unavoidable, prefix EVERY class** with a component abbreviation
|
||||
(`ah-col-id`, `il-incidents-table`). Vite bundles global CSS in dependency order; two components
|
||||
sharing a generic class like `.col-id` → the last-bundled one silently wins, no warning. **Grep
|
||||
for a class before adding `:global()`.**
|
||||
3. **Always set `tbody tr` background explicitly in dark mode.** Any `overflow:auto` container
|
||||
(`.table-wrapper`) creates an opaque scroll region — the card's dark bg does NOT show through, the
|
||||
browser fills white. Set `:global(.dark-mode) tbody tr { background:#1f2937 }` (+ `:hover #374151`,
|
||||
and `table`/`.table-wrapper` `background:transparent`). Every table, every time.
|
||||
4. **Table `td` font-size is ALWAYS `var(--font-size-label)` (0.85rem)** — never `--font-size-body`
|
||||
(0.95rem). The 0.95 vs 0.85 difference makes the whole table look ~12% larger than every other app.
|
||||
|
||||
## Data formatting
|
||||
|
||||
**`toLowerCase()` before title-casing enum strings.** Backend enums arrive as
|
||||
`SCREAMING_SNAKE_CASE`; a title-case that skips lowercasing yields `CARD READER FAIL` (all-caps,
|
||||
visually larger) instead of `Card Reader Fail`:
|
||||
|
||||
```typescript
|
||||
type.replace(/_/g, ' ').toLowerCase().replace(/\b\w/g, c => c.toUpperCase()); // "Card Reader Fail"
|
||||
```
|
||||
|
||||
## Header & structure (also enforced by the `svelte-template-lint` hook)
|
||||
|
||||
Header is **text only** — action buttons (Add/Refresh/Compose) go in `.toolbar-right` inside the
|
||||
content frame, never in `.header`. Add/Edit forms are **slide-in panels**, not centered modals.
|
||||
Locked structure: `.filter-sidebar` · `.content-frame` · `.table-card` border · active-filter chips ·
|
||||
`Pagination` at top-of-table. New page → **copy** TablePage/TemplatePage first; existing page → verify
|
||||
it conforms before building on it (many drifted).
|
||||
Reference in New Issue
Block a user