Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .github/workflows/chromatic.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Chromatic Visual Regression Testing
# https://www.chromatic.com/docs/github-actions/

name: Chromatic

on:
push:
branches: [main]
pull_request:
branches: [main]

permissions:
contents: read

jobs:
chromatic:
name: Run Chromatic
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Install Pnpm
run: npm install -g corepack@latest --force && corepack enable

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 24.11.1
cache: 'pnpm'

- name: Install dependencies
run: pnpm install

- name: Build Storybook
run: pnpm run build-storybook

- name: Run Chromatic
uses: chromaui/action@latest
with:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
# Use the pre-built Storybook
storybookBuildDir: storybook-static
# Auto accept changes on main branch (for squash/rebase merge)
autoAcceptChanges: main
# Don't fail CI when there are visual changes - require review in Chromatic UI
exitZeroOnChanges: true
# Skip builds for dependabot/renovate branches
skip: '@(renovate/**|dependabot/**)'
172 changes: 172 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# AGENTS.md

Shared UI component library (`@rstack-dev/doc-ui`) for Rstack websites (rspack.rs, rsbuild.rs, rspress.rs).

## Tech Stack

- React 18 + TypeScript 5.9 (strict mode)
- Build: Rslib (based on Rsbuild)
- Styling: SCSS Modules (`.module.scss`)
- Animation: Framer Motion, Lottie
- UI: Ant Design 6
- Dev: Storybook 10

## Commands

```bash
# Development
pnpm dev # Start Storybook (port 6006)

# Build
pnpm build # Build with Rslib
pnpm build:watch # Watch mode

# Lint (prefer file-scoped)
pnpm lint # Check all with Biome
pnpm lint:fix # Auto-fix

# Single file commands
npx tsc --noEmit 'path/to/file.tsx'
npx prettier --write 'path/to/file.tsx'
npx biome check --write 'path/to/file.tsx'
```

No test framework - visual testing via Storybook.

## Project Structure

```
src/
├── announcement/ # Announcement banner
├── antd/ # Ant Design wrappers
├── background-image/ # Background component
├── benchmark/ # Benchmark display
├── built-with-rspack/ # Showcase component
├── fully-featured/ # Feature list
├── hero/ # Hero section
├── nav-icon/ # Nav icon with popover
├── section-style/ # Section utilities
├── tool-stack/ # Tool stack display
├── why-rspack/ # Feature cards
├── env.d.ts # Type declarations
└── shared.tsx # Shared utilities

stories/ # Storybook stories
```

## Code Style

### Formatting (Prettier - `.prettierrc`)

- Single quotes, trailing commas (`all`), no parens for single arrow params

### Linting (Biome - `biome.json`)

- `noExplicitAny`: off, `noArrayIndexKey`: off
- File naming: `camelCase`, `PascalCase`, or export name

### TypeScript

- Strict mode, use `type` imports: `import type { FC } from 'react'`
- Path alias: `@/*` → `./src/*`

### Imports Order

1. External packages (react, antd, framer-motion)
2. Internal components (relative)
3. Styles (`.module.scss`)
4. Assets (JSON, images)

```typescript
import type { FC } from 'react';
import { useState } from 'react';
import { useInView } from 'react-intersection-observer';
import { ProgressBar } from './ProgressBar';
import styles from './index.module.scss';
```

## Component Patterns

### Naming

- Components: `PascalCase` (`Hero`, `NavIcon`)
- Hooks: `useCamelCase` (`useMouseMove`)
- Props: `ComponentNameProps` (`HeroProps`)
- Styles: `index.module.scss` per component

### Structure

```typescript
import type { FC } from 'react';
import styles from './index.module.scss';

export type MyComponentProps = {
title: string;
active?: boolean;
};

export const MyComponent: FC<MyComponentProps> = ({
title,
active = false,
}) => {
return <div className={styles.root}>{title}</div>;
};
```

### Styling

- SCSS Modules only (`.module.scss`)
- Compose: `${styles.btn} ${styles.btnPrimary}`
- Root class: `styles.root`

## Do / Don't

### Do

- Functional components with hooks
- SCSS Modules for styling
- Export types with components
- Semantic HTML (`section`, `button`)
- Default values for optional props
- `memo()` for expensive components

### Don't

- Inline styles (except dynamic values)
- CSS-in-JS (emotion, styled-components)
- Hard-coded colors
- Class components
- Heavy deps without consideration

## Storybook

```typescript
// stories/Hero.stories.tsx
import { Hero } from '@rstack-dev/doc-ui/hero';
import './index.scss';

export const HeroStory = () => <Hero onClickGetStarted={() => {}} />;

export default { title: 'Hero' };
```

## Git Hooks

Pre-commit via `simple-git-hooks` + `nano-staged`:

- Biome lint on JS/TS
- Prettier format on all files

## Adding Components

1. Create `src/component-name/index.tsx`
2. Add `src/component-name/index.module.scss`
3. Add entry in `rslib.config.ts`
4. Add export in `package.json` exports
5. Create `stories/ComponentName.stories.tsx`

## External Dependencies

Externalized (consumers provide): `react`, `react-dom`, `framer-motion`

Peer deps: `antd`, `lottie-web`, `react-intersection-observer`
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@
"build:watch": "rslib build -w",
"lint": "biome check",
"lint:fix": "biome check --write --unsafe",
"bump": "npx bumpp"
"bump": "npx bumpp",
"chromatic": "chromatic"
},
"dependencies": {
"framer-motion": "^12.23.25"
Expand All @@ -90,10 +91,12 @@
"@rstack-dev/doc-ui": "workspace:*",
"@storybook/addon-themes": "^10.1.5",
"@storybook/react": "^10.1.5",
"@storybook/test": "9.0.0-alpha.2",
"@types/node": "~24.10.2",
"@types/react": "^18.3.27",
"@types/react-dom": "^18.3.7",
"antd": "^6.1.0",
"chromatic": "^13.3.5",
"execa": "9.6.1",
"fs-extra": "11.3.2",
"lottie-web": "5.13.0",
Expand Down
Loading