DOL Platform Evolution - Centralized UI & Components
Status: Phase P1 + P1.1 shipped. P2 pending cross-repo approval. Scope: Cross-repo architecture (DS-Token, Wiki, Playground, Design System Studio). Authority: Design System owner, per Approval Matrix in workspace CLAUDE.md. Canonical product name: Design System Studio (locked 2026-04-24). Short form “DS Studio” acceptable in casual context. Package (
@dol/ds-studio), folder (studio/), URL (/design-system/) unchanged. Every user-facing string (HTML title, in-app logo, dev-server banner, README, CHANGELOG) updated on rename day.
1. Vision
Section titled “1. Vision”“Các component và UI tái sử dụng được tập trung vào một nơi. Các product khác tham khảo từ đó để xây dựng → đồng bộ thiết kế giữa các product khác nhau.” - user direction, 2026-04-24
Design System Studio is the single destination for:
- browsing every design token,
- reading every DS guideline,
- referencing every shared component,
- and - in the long term - the home of the shared UI layer itself.
Every DOL product (Wiki, Playground, future apps) consumes from the DS-Token repo; Design System Studio is the human-readable face of that source of truth.
2. Current state (2026-04-24)
Section titled “2. Current state (2026-04-24)”What IS centralized (working)
Section titled “What IS centralized (working)”- Design tokens -
DS-Token/tokens/v4/→ propagated to Wiki, Playground, Studio viagenerate-subset.js. Any token change reaches every consumer on next build. Proven path.
What is NOT centralized (friction)
Section titled “What is NOT centralized (friction)”| Asset | Where it lives | Pain |
|---|---|---|
| General UI components (15) | dol-edu-playground/components/ui/*.tsx | Wiki can’t import - they’d rebuild Button/Card from scratch. |
| KID components (9) | dol-edu-playground/components/Domains/DolKid/ui/*.tsx | Same - Kid UI is Playground-locked. |
| Doc page shell (sidebar, TOC, article) | DOL Wiki/site/src/components/ClientSidebar.tsx + [[...slug]]/page.tsx | Studio’s docs surface duplicated every piece in vanilla JS. |
| Prose styles | Studio’s .prose-docs + Wiki’s .docx-resource | Two implementations of the same intent - drift risk. |
| Doc corpus (MD files) | DS-Token/design-guideline/**/*.md (25 files) | ✓ lives with DS-Token, but no consumer besides Studio knows about them. |
Root cause: each repo treats “UI reusability” as its local concern. No repo is positioned as the host.
3. Target state
Section titled “3. Target state”DOL-DS-token/ ← single source of truth├── tokens/ (existing - token layer)├── components/ (NEW - React component layer)│ ├── ui/ 15 general UI primitives│ ├── kid/ 9 KID-domain components│ └── doc-shell/ sidebar, article, TOC, breadcrumb (extracted from Wiki)├── ui-css/ (NEW - shared CSS layer)│ ├── prose.css .dol-prose - doc article body│ ├── doc-shell.css layout for sidebar/article/TOC│ └── code-block.css copy button + language label├── design-guideline/ (existing - doc corpus)├── studio/ (existing - catalog + preview)└── dist/ ├── tokens-data.json (existing) ├── components/ (NEW - built React + types) └── ui-css/ (NEW - shared CSS bundles)
Consumers: Wiki → import { Button, Card, DocShell } from '@dol/ds-token/components' → import '@dol/ds-token/ui-css/prose.css' Playground → same imports; stops HOSTING, just references Studio → catalog-renders from DS-Token component manifest Future apps → default path is DS-Token importKey shift: Playground transitions from host of shared components → consumer of them. Its role narrows to “spec → demo pipeline + domain-specific logic”.
4. Migration phases
Section titled “4. Migration phases”Each phase ships independently + is reversible. Estimated cost + blast radius tagged. Stop at any gate if the trade-off becomes wrong.
✅ P1 - Extract shared CSS (shipped 2026-04-24)
Section titled “✅ P1 - Extract shared CSS (shipped 2026-04-24)”Moved Design System Studio’s .prose-docs, code-block decorator, doc-shell
layout → DS-Token/ui-css/*.css with canonical class .dol-prose +
backward-compat alias. Studio imports via @import '../../../ui-css/...'.
- Landed files:
ui-css/prose.css,ui-css/README.md,studio/src/styles/tailwind.css(imports),studio/index.html(class rename) - Shipped also:
ui-css/palette-remap-invariant.css(auto-generated compatibility variant for Tailwind-convention consumers - see lesson on double-flip bug that surfaced this need) - Next consumers ready to opt in: Wiki (P3), Playground (P2)
✅ P1.1 - Doc-shell layout extraction (shipped 2026-04-24)
Section titled “✅ P1.1 - Doc-shell layout extraction (shipped 2026-04-24)”Extracted the 3-column reading layout (sidebar + article + TOC) as
canonical classes in ui-css/doc-shell.css - .dol-doc-layout,
.dol-doc-sidebar, .dol-doc-main, .dol-doc-article-wrap,
.dol-doc-article-header, .dol-doc-toc. Wiki + Playground can adopt these
in a single import when doing P3/P4.
P1.2 - Dark-variant tech debt purge (1 day, when scheduled)
Section titled “P1.2 - Dark-variant tech debt purge (1 day, when scheduled)”Canonical DOL convention = auto-flipping neutrals, NO dark:*-color-*
variants. Studio currently has 232 dark:*-slate-* + ~359 total color
dark variants. The invariant palette shim makes them work; removing them
(and letting auto-flip handle theme) aligns Studio with Wiki + DOL canon.
- Files touched: 10+ (index.html, controllers, components)
- Blast radius: Studio visual (every surface)
- Verification gate: every screen identical in light + dark after purge
- Pre-req: visual diff tooling OR careful manual pass
⏸ P2 - Move components to DS-Token (3–5 days, cross-repo - needs approval)
Section titled “⏸ P2 - Move components to DS-Token (3–5 days, cross-repo - needs approval)”Relocate Playground/components/ui/* + Playground/components/Domains/DolKid/ui/*
→ DS-Token/components/. Playground updates import paths to reference
DS-Token via workspace link (file: dep) or internal package.
- Files touched: DS-Token (new), Playground (import rewrites × ~24 files)
- Blast radius: Playground (all consumers of moved components)
- Verification gate: Playground dev + prod build pass; visual unchanged
- Reversibility: git revert; path aliases keep working both ways
- Enables: Wiki + future products to import from DS-Token
- Blocker: workspace CLAUDE.md approval matrix requires explicit plan-approval for cross-repo destructive changes. Awaiting user greenlight.
P3 - Wiki consumes DS-Token components (5–7 days, higher risk)
Section titled “P3 - Wiki consumes DS-Token components (5–7 days, higher risk)”Inventory Wiki’s site/src/components/*.tsx. Categorize:
-
Truly generic (Button, Card, etc.) → migrate consumption to DS-Token
-
Wiki-specific (GraphClient, AiMarkdown, CitationSpanChip, etc.) → stay in Wiki
-
Doc shell (ClientSidebar, Header,
[[...slug]]/page.tsxlayout) → extract to DS-Token’scomponents/doc-shell/so Studio + future doc surfaces reuse -
Files touched: Wiki (import rewrites + extraction), DS-Token (new doc-shell)
-
Blast radius: Wiki - all pages using affected components
-
Verification gate: Wiki dev + CI + visual regression
-
Reversibility: extractions are additive; old components remain until gate passes
P4 - Design System Studio’s Docs surface = Wiki-served (3–5 days, low-medium risk)
Section titled “P4 - Design System Studio’s Docs surface = Wiki-served (3–5 days, low-medium risk)”Wiki hosts /design-system/docs/* using the shared doc-shell components now
in DS-Token. Studio’s Docs tab navigates there; user stays under same URL root.
- Prerequisites: P3 doc-shell extraction done (so Wiki’s doc page uses the shared shell that matches Studio’s visual language)
- Files touched: Wiki (new route + content-provider config to read
DS-Token/design-guideline/), Studio (Docs tab becomes redirect) - Blast radius: Studio’s Docs surface (removed) + Wiki (new routes)
- Verification gate: URL routing + content rendering + shell consistency
- Answers Q1/Q2/Q3 from the previous message - see §7 below
P5 - Component live previews unified (1–2 weeks, delayed)
Section titled “P5 - Component live previews unified (1–2 weeks, delayed)”Replace Studio’s inline HTML approximations (Path A from F4) with actual rendered DS-Token React components via iframe or SSG capture.
- Prerequisites: P2 + P3 (components centralized)
- Blast radius: Studio (preview mechanism swap)
- Deferred until: P1–P4 stable + users ask for real previews
5. Cost summary (updated 2026-04-24)
Section titled “5. Cost summary (updated 2026-04-24)”| Phase | Status | Effort | Risk | Value |
|---|---|---|---|---|
| P1 | ✅ shipped | 1 day | Low | Shared CSS baseline (ui-css/prose.css) |
| P1.1 | ✅ shipped | 0.5 day | Low | Shared doc-shell layout (ui-css/doc-shell.css) |
| P1.2 | ⏸ tech debt | 1 day | Low | Purge dark:*-color-* variants, adopt auto-flip |
| P2 | ⏸ needs approval | 3–5 days | Medium | Components move Playground → DS-Token |
| P3 | ⏸ downstream | 5–7 days | Higher | Wiki consumes DS-Token components + doc-shell |
| P4 | ⏸ downstream | 3–5 days | Low-Med | Docs tab delegated to Wiki |
| P5 | ⏸ future | 1–2 weeks | Medium | Live component previews (replace Path A) |
Total remaining (P1.2 + P2 + P3 + P4): ~2–3 weeks. P5 is additive later.
6. What this vision does NOT require
Section titled “6. What this vision does NOT require”Explicitly out-of-scope to keep the plan tractable:
- No public npm publishing. Workspace-link consumption is enough for private use.
- No new repo. DS-Token expands in scope, not count.
- No framework change. Each app keeps its stack (Wiki = Next.js, Playground = Vite+React, Studio = Vite+vanilla).
- No immediate rewrite of Wiki-specific features (graph, AI search, citations).
- No forced component rename. Import paths change; public APIs stay stable.
7. Open decisions (blockers for P1 start)
Section titled “7. Open decisions (blockers for P1 start)”These 4 questions shape the spec. Best answered by the owner before P1 begins.
D1 - Package form: DS-Token consumed by other repos as…
- (a) Workspace-link (
"@dol/ds-token": "file:../DOL-DS-token") + symlink. Simplest. - (b) Private npm registry publish per release. More overhead.
- (c) Git submodule. Rare in DOL workspace. Discouraged.
Default if silent: (a). Low risk, reversible to (b) later.
D2 - Component file convention: components in DS-Token/components/ are…
- (a) TSX files, consumed directly. Consumer apps handle compilation.
- (b) Pre-built (
vite-plugin-dts+tsc) at DS-Token, consumers import compiled output. - (c) Both - source for type-checking, build for runtime.
Default if silent: (a). Matches Playground’s current setup.
D3 - MD source for Wiki docs (from previous message’s Q2): Wiki reads DS-Token’s guideline corpus via…
- (a) FS provider reading
../DOL-DS-token/design-guideline/. Workspace-local. - (b) GitHub provider (HTTPS) reading from
DOL-DS-tokenrepo. Prod-compatible. - (c) Files move into Wiki. DS-Token loses them.
Default if silent: (a) for dev, (b) for prod. Wiki’s provider already supports both.
D4 - Visual shell consistency on Wiki-served docs: /design-system/docs/* shows…
- (a) Studio’s tab nav (Tokens / Docs / Components) at top + Wiki’s shell below. Unified UX.
- (b) Wiki’s native header only. Simpler but user feels “moved to Wiki”.
Default if silent: (a). Aligns with “single platform” vision.
8. Start condition
Section titled “8. Start condition”P1 begins when any 1 of 4 decisions has a non-default answer (worth stopping to confirm) OR when owner explicitly greenlights defaults. If none arrive within a reasonable window, proceed with defaults and note each choice in the P1 commit message for reviewability.
9. Glossary
Section titled “9. Glossary”- Design System Studio (canonical product name, locked 2026-04-24):
the SPA at
dol-wiki.khoajak.design/design-system/. Single destination for tokens, docs, components. Short form “DS Studio” acceptable in casual context. Package@dol/ds-studio, folderstudio/. - DS-Token: the
DOL-DS-token/repo - host of tokens + docs corpus +ui-css/shared styles + (future P2)components/shared React components. Design System Studio lives inside this repo asstudio/subfolder. - Wiki: the Next.js site at
dol-wiki.khoajak.design/wiki/- DOL’s knowledge hub. Future P3 consumer of DS-Token components. Future P4 host of Design System Studio’s Docs tab. - Playground:
dol-edu-playground/- runtime demo + spec mapping source. Current home of 24 shared components; P2 moves them to DS-Token. - Doc shell: sidebar + article + TOC + breadcrumb - the chrome around
rendered doc content. Canonical layout classes in
ui-css/doc-shell.css. - ui-css/: shared CSS layer at DS-Token root. Framework-agnostic
(vanilla JS, React, Next.js all consume). Currently:
prose.css,doc-shell.css,palette-remap-invariant.css. - Auto-flip convention: DOL canonical theme-flipping pattern - designer
writes
text-slate-900alone; neutrals flip per[data-theme="dark"]automatically via palette-remap’s alias chain. NOdark:*-slate-*. - Invariant palette: compatibility variant (
palette-remap-invariant.css) for products using Tailwind’s explicitdark:convention. Prevents double-flip when code has both conventions competing.
Navigation
Section titled “Navigation”- Hub: overview.md
- Related: ds-guideline/DIRECTION.md (design philosophy)
- Prior:
ai-memory/lessons/studio-platform-expansion-2026-04-24.md(how current state was built)