From 7dfd0df6b3914202ffc6f6950de998ac44ee7108 Mon Sep 17 00:00:00 2001 From: Hermann_Kitio Date: Sat, 18 Apr 2026 01:25:54 +0300 Subject: [PATCH] =?UTF-8?q?feat(design-system):=20page=20/design-system=20?= =?UTF-8?q?dev-only=20=E2=80=94=20palette=20live=20+=20composants=20(Sprin?= =?UTF-8?q?t=200.5=20=C3=A9tape=207)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/router.tsx | 15 ++ .../design-system/DesignSystemPage.tsx | 248 ++++++++++++++++++ 2 files changed, 263 insertions(+) create mode 100644 src/features/design-system/DesignSystemPage.tsx diff --git a/src/app/router.tsx b/src/app/router.tsx index dfe0538..9f09a3e 100644 --- a/src/app/router.tsx +++ b/src/app/router.tsx @@ -1,9 +1,24 @@ +import React, { Suspense } from 'react' import { Routes, Route } from 'react-router-dom' +const DesignSystemPage = import.meta.env.DEV + ? React.lazy(() => import('@/features/design-system/DesignSystemPage')) + : () => null + export function AppRouter() { return ( } /> + {import.meta.env.DEV && ( + Loading…}> + + + } + /> + )} ) } diff --git a/src/features/design-system/DesignSystemPage.tsx b/src/features/design-system/DesignSystemPage.tsx new file mode 100644 index 0000000..27edc6f --- /dev/null +++ b/src/features/design-system/DesignSystemPage.tsx @@ -0,0 +1,248 @@ +import React, { useState } from 'react' +import { useTheme } from '@/shared/hooks/useTheme' +import { Button } from '@/shared/components/ui/button' +import { Badge } from '@/shared/components/ui/badge' +import { Input } from '@/shared/components/ui/input' +import { Label } from '@/shared/components/ui/label' +import { Separator } from '@/shared/components/ui/separator' +import { Progress } from '@/shared/components/ui/progress' +import { + Avatar, + AvatarFallback, + AvatarImage, + AvatarGroup, + AvatarGroupCount, +} from '@/shared/components/ui/avatar' +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from '@/shared/components/ui/dialog' + +// ─── palette data ──────────────────────────────────────────────────────────── + +const PALETTE: { token: string; var: string; light: string; dark: string }[] = [ + { token: 'canvas', var: '--color-canvas', light: '#EEF2F8', dark: '#0D1220' }, + { token: 'canvas-2', var: '--color-canvas-2', light: '#E6EBF4', dark: '#121A2D' }, + { token: 'surface', var: '--color-surface', light: '#FFFFFF', dark: '#182238' }, + { token: 'surface-hover',var: '--color-surface-hover',light: '#F8FAFD', dark: '#1E2A42' }, + { token: 'line', var: '--color-line', light: '#DDE3ED', dark: '#27324B' }, + { token: 'line-strong', var: '--color-line-strong', light: '#C7D0E0', dark: '#364363' }, + { token: 'ink-1', var: '--color-ink-1', light: '#0F172A', dark: '#F1F4FA' }, + { token: 'ink-2', var: '--color-ink-2', light: '#1E293B', dark: '#DDE3EF' }, + { token: 'ink-3', var: '--color-ink-3', light: '#475569', dark: '#A8B2C7' }, + { token: 'ink-4', var: '--color-ink-4', light: '#64748B', dark: '#7A8499' }, + { token: 'ink-5', var: '--color-ink-5', light: '#94A3B8', dark: '#525C73' }, + { token: 'expria', var: '--color-expria', light: '#1B4FD8', dark: '#5B7FFF' }, + { token: 'expria-hover', var: '--color-expria-hover', light: '#1741B8', dark: '#6F8EFF' }, + { token: 'expria-50', var: '--color-expria-50', light: '#EEF3FF', dark: 'rgba(91,127,255,.12)' }, + { token: 'expria-100', var: '--color-expria-100', light: '#DCE6FF', dark: '—' }, + { token: 'expria-200', var: '--color-expria-200', light: '#B8CDFF', dark: '—' }, + { token: 'deep', var: '--color-deep', light: '#0B1F5C', dark: '#060B1A' }, + { token: 'success', var: '--color-success', light: '#0E9F6E', dark: '#3DD68C' }, + { token: 'success-bg', var: '--color-success-bg', light: '#E6F6F0', dark: 'rgba(61,214,140,.12)' }, + { token: 'warning', var: '--color-warning', light: '#C77A00', dark: '#F5B849' }, + { token: 'warning-bg', var: '--color-warning-bg', light: '#FEF3E2', dark: 'rgba(245,184,73,.12)' }, + { token: 'danger', var: '--color-danger', light: '#C53030', dark: '#F06B6B' }, + { token: 'danger-bg', var: '--color-danger-bg', light: '#FDECEC', dark: 'rgba(240,107,107,.12)' }, +] + +// ─── section wrapper ───────────────────────────────────────────────────────── + +function Section({ title, children }: { title: string; children: React.ReactNode }) { + return ( +
+

{title}

+ + {children} +
+ ) +} + +// ─── main page ─────────────────────────────────────────────────────────────── + +export default function DesignSystemPage() { + const { theme, setTheme } = useTheme() + const [dialogOpen, setDialogOpen] = useState(false) + + return ( +
+ + {/* ── header ── */} +
+
+

Design System

+

Expria — Direction H palette · Sprint 0.5

+
+ +
+ + {/* ── palette ── */} +
+
+ {PALETTE.map(({ token, var: cssVar, light, dark }) => ( +
+
+
+

{token}

+

+ ☀ {light} +

+

+ ☾ {dark} +

+
+
+ ))} +
+
+ + {/* ── typography ── */} +
+
+

Display / 36px Bold

+

Heading 1 / 24px Semibold

+

Heading 2 / 20px Semibold

+

Heading 3 / 18px Medium

+

Body / 16px Regular — Plus Jakarta Sans

+

Small / 14px Regular — secondary copy

+

Caption / 12px Regular — labels, metadata

+

Mono / 12px — token names, code

+
+
+ + {/* ── buttons ── */} +
+
+
+ + + + + + +
+
+ + + + +
+
+ + +
+
+
+ + {/* ── badges ── */} +
+
+ Default + Secondary + Outline + Destructive +
+
+ + {/* ── inputs / forms ── */} +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +

Content below separator

+
+
+ + {/* ── avatar ── */} +
+
+
+ + + HK + + sm +
+
+ + + HK + + default +
+
+ + + HK + + lg +
+
+ + {['AB', 'CD', 'EF'].map(initials => ( + + {initials} + + ))} + +5 + + group +
+
+
+ + {/* ── dialog ── */} +
+
+ + + + + + + Example dialog + + This dialog uses Direction H tokens — bg-surface, border-line, text-ink-4. + Toggle the theme to see it adapt. + + + + + + + +
+
+ +
+ ) +}