storybook github

astro — 1thay documentation site

build target: 1thay.com · deploy: cloudflare pages · linked files: 1thay.md, design-tokens.md, storybook.md, CLAUDE.md


overview

astro builds the 1thay design system documentation site. it uses react components from src/components/, design tokens from src/tokens/, and follows conventions from 1thay.md.

site structure: home hub → foundations → components → patterns


project config

astro.config.mjs

import { defineConfig } from 'astro/config';
import react from '@astrojs/react';

export default defineConfig({
  integrations: [react()],
  output: 'static',
  site: 'https://1thay.com',
});

package.json scripts

{
  "dev": "astro dev",
  "build": "astro build",
  "preview": "astro preview",
  "lint": "astro check",
  "sync": "astro sync"
}

deploy

setting value
platform cloudflare pages
repo kien-day/1thay-com
branch main
framework astro
build command npm run build
output directory dist/
domain 1thay.com
preview 1thay-com.pages.dev

directory structure

src/
├── tokens/               # design-tokens.md — single source of truth
│   ├── tokens.css          imported by both astro + storybook
│   └── tokens.js           js export (storybook theme)
├── components/             # react components — shared with storybook.md
│   ├── Button/
│   ├── Card/
│   ├── Input/
│   └── Icon/
├── layouts/
│   ├── BaseLayout.astro    # root layout: fonts, global css, <html>/<head>/<body>
│   └── DocsLayout.astro    # documentation layout: sidebar nav + content
├── pages/
│   ├── index.astro         # home hub — links to all 3 sections
│   ├── foundations/
│   │   ├── index.astro      # overview + card links
│   │   ├── colors.astro     # brand palettes + neutral + semantic
│   │   ├── typography.astro # 4 fonts + type scale + weights
│   │   ├── spacing.astro    # spacing, radius, shadows, opacity, z, sizes
│   │   └── iconography.astro# lucide (line) + carbon (fill) demo
│   ├── components/
│   │   ├── index.astro      # overview + card links
│   │   ├── button.astro     # variants, sizes, states, tokens
│   │   ├── card.astro       # variants, anatomy, tokens
│   │   └── input.astro      # sizes, label/helper, validation, tokens
│   └── patterns/
│       ├── index.astro      # overview + card links
│       ├── signup.astro     # single-step + multi-step flow
│       ├── layout.astro     # dashboard, bento, sidebar, centered
│       ├── navigation.astro # top nav, sidebar, breadcrumbs, tabs
│       └── data-visualize.astro # metric cards, chart layout, principles
└── styles/
    └── global.css           # base reset + token import + typography defaults

layout system

BaseLayout

wraps every page. provides:

  • <html lang="vi"> + charset + viewport
  • google fonts preconnect + link (Hanken Grotesk, Inter, Merriweather, Space Grotesk)
  • <title> via slot/head propagation
  • imports src/styles/global.css which imports src/tokens/tokens.css
  • top navbar (56px, sticky): logo "1thay" → foundations | components | patterns + storybook/github links
    • active section auto-detected from Astro.url.pathname
    • external links marked with
    • responsive: external links hidden on mobile
  • <slot /> for page content

DocsLayout

extends BaseLayout for documentation pages. provides:

  • sidebar (260px, sticky, --surface-dim background)
    • logo link to /
    • foundations group: overview, colors, typography, spacing, iconography
    • components group: overview, button, card, input
    • patterns group: overview, signup, layout, navigation, data viz
    • footer: storybook + github links
  • content area (flex 1, max-width 960px, padding --space-3xl)
    • <h1> from title prop with bottom border
    • <slot /> for page content
  • responsive: sidebar collapses to top on mobile (< 768px)

props:

interface Props {
  title: string;                                           // h1 content
  section: 'foundations' | 'components' | 'patterns';     // active nav section
}

component rules

react components in astro

  • react components receive react-style props (camelCase, style objects), not html-style
  • critical: never pass string style prop to react components in astro — it expects style={{...}}
  • for layout spacing, wrap react components in astro <div style="..."> elements
  • use client:load directive for interactive components (Input)

page conventions

  • each documentation page imports DocsLayout and sets title + section
  • token values displayed as code blocks: <code>value</code>
  • visual demos use live tokens via css custom properties
  • pages are static — no client-side js except for interactive components

adding a new foundation page

  1. create src/pages/foundations/name.astro
  2. add to DocsLayout.astro sidebar under foundations group
  3. add card link to src/pages/foundations/index.astro
  4. update this file and project-logs.md

adding a new component page

  1. build component in storybook first (see storybook.md)
  2. create src/pages/components/name.astro
  3. add to DocsLayout.astro sidebar under components group
  4. add card link to src/pages/components/index.astro
  5. update this file and project-logs.md

adding a new pattern page

  1. create src/pages/patterns/name.astro
  2. add to DocsLayout.astro sidebar under patterns group
  3. add card link to src/pages/patterns/index.astro
  4. update this file and project-logs.md

fonts

all fonts loaded via google fonts in BaseLayout.astro:

family weights css variable use
Hanken Grotesk 600, 700 --font-display hero, h1-h4
Inter 400, 500 --font-text body, ui, labels
Merriweather 400 --font-content long-form reading
Space Grotesk 500, 600 --font-number data, metrics

icons

set package type use
lucide lucide-react line stroke function, navigation, modules
carbon @carbon/icons-react shape fill data, mini actions

wrapper components in src/components/Icon/:

  • <Icon> — lucide line icons, 4 sizes (sm/md/lg/xl)
  • <IconFill> — carbon fill icons, 4 sizes

linked references