Skip to content

Commit 7621d41

Browse files
authored
add: docs (#551)
1 parent c6054b5 commit 7621d41

File tree

12 files changed

+8023
-0
lines changed

12 files changed

+8023
-0
lines changed

docs/ARCHITECTURE.md

Lines changed: 398 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,398 @@
1+
# Architecture
2+
3+
This document describes the system architecture, project structure, and build process for the Raven Design System.
4+
5+
## Table of Contents
6+
7+
- [Project Structure](#project-structure)
8+
- [Build System](#build-system)
9+
- [Module System](#module-system)
10+
- [Component Architecture](#component-architecture)
11+
- [Dependency Management](#dependency-management)
12+
- [Configuration Files](#configuration-files)
13+
14+
## Project Structure
15+
16+
```
17+
rds/
18+
├── lib/ # Source code
19+
│ ├── components/ # 51 UI components
20+
│ │ ├── Alert/
21+
│ │ │ ├── Alert.tsx # Component implementation
22+
│ │ │ ├── Alert.stories.tsx # Storybook stories
23+
│ │ │ └── styles.css # Component styles
24+
│ │ └── ...
25+
│ ├── layouts/ # 10 layout components
26+
│ ├── data/ # Sample data for stories (26 files)
27+
│ ├── helpers/ # Validation schemas, utilities
28+
│ ├── hooks/ # Custom React hooks (3 hooks)
29+
│ ├── styles/ # Global CSS files
30+
│ ├── utils/ # Utility functions and prop classes
31+
│ ├── docs/ # Storybook MDX documentation
32+
│ ├── main.ts # Main export barrel file
33+
│ └── style.css # Primary CSS entry point
34+
35+
├── .storybook/ # Storybook configuration
36+
│ ├── main.ts # Main config
37+
│ └── preview.ts # Preview config
38+
39+
├── cypress/ # E2E and component tests
40+
│ ├── e2e/ # E2E test files
41+
│ ├── fixtures/ # Test fixtures
42+
│ └── support/ # Test helpers
43+
44+
├── public/ # Static assets
45+
│ ├── assets/
46+
│ │ ├── font-awesome/ # Icons
47+
│ │ └── bg-images/ # Background images
48+
│ └── sample-imgs/ # Sample images for demos
49+
50+
├── dist/ # Build output (generated)
51+
│ ├── rds.es.js # ES module bundle
52+
│ ├── rds.umd.js # UMD bundle
53+
│ ├── main.d.ts # TypeScript declarations
54+
│ └── style.css # Compiled CSS
55+
56+
└── Configuration files
57+
├── vite.config.ts # Vite/Rollup configuration
58+
├── tailwind.config.ts # Tailwind CSS configuration
59+
├── tsconfig.json # TypeScript configuration
60+
├── eslint.config.mjs # ESLint configuration
61+
├── .prettierrc # Prettier configuration
62+
├── cypress.config.ts # Cypress configuration
63+
└── package.json # Dependencies and scripts
64+
```
65+
66+
## Build System
67+
68+
### Vite + Rollup
69+
70+
The library uses Vite 6.3 with Rollup for production builds.
71+
72+
**Key Configuration** (`vite.config.ts`):
73+
74+
```typescript
75+
export default defineConfig({
76+
plugins: [react(), dts({ rollupTypes: true })],
77+
build: {
78+
lib: {
79+
entry: resolve(__dirname, 'lib/main.ts'),
80+
name: 'rds',
81+
formats: ['es', 'umd'],
82+
fileName: (format) => `rds.${format}.js`,
83+
},
84+
rollupOptions: {
85+
external: [/* all dependencies externalized */],
86+
output: {
87+
globals: {
88+
react: 'React',
89+
'react-dom': 'ReactDOM',
90+
// ... other globals
91+
},
92+
},
93+
},
94+
},
95+
})
96+
```
97+
98+
### Build Outputs
99+
100+
| Output | Format | Use Case |
101+
|--------|--------|----------|
102+
| `dist/rds.es.js` | ES Modules | Modern bundlers (Vite, webpack 5+) |
103+
| `dist/rds.umd.js` | UMD | Browser `<script>` tags, older bundlers |
104+
| `dist/main.d.ts` | TypeScript | Type definitions |
105+
| `dist/style.css` | CSS | Compiled styles |
106+
107+
### Bundle Size Limits
108+
109+
Enforced via `size-limit` package:
110+
111+
```json
112+
{
113+
"size-limit": [
114+
{ "path": "dist/rds.es.js", "limit": "200 kB" },
115+
{ "path": "dist/rds.umd.js", "limit": "200 kB" }
116+
]
117+
}
118+
```
119+
120+
### Build Scripts
121+
122+
```bash
123+
# Full build (lint, format, compile, size check)
124+
npm run build
125+
126+
# Storybook build
127+
npm run build:storybook
128+
129+
# Generate asset lists
130+
npm run create-lists
131+
```
132+
133+
### CSS Processing
134+
135+
PostCSS pipeline with:
136+
1. **Tailwind CSS** - Utility-first styles
137+
2. **PostCSS Nesting** - CSS nesting support
138+
3. **Autoprefixer** - Browser prefixes
139+
140+
## Module System
141+
142+
### Export Pattern
143+
144+
The library uses a **barrel export pattern** in `lib/main.ts`:
145+
146+
```typescript
147+
// Components
148+
export { Alert } from './components/Alert/Alert'
149+
export { Button } from './components/Button/Button'
150+
export { Card } from './components/Card/Card'
151+
// ... 50+ more
152+
153+
// Layouts
154+
export { Article } from './layouts/Article/Article'
155+
export { Column } from './layouts/Column/Column'
156+
// ... more layouts
157+
158+
// Utilities
159+
export * as utils from './utils/propClasses'
160+
export { iconNames } from '../public/assets/font-awesome/icon-list.js'
161+
export { bgImageNames } from '../public/assets/bg-images/bg-image-list.js'
162+
163+
// CSS (side effect)
164+
import './style.css'
165+
```
166+
167+
### Package Exports
168+
169+
```json
170+
{
171+
"exports": {
172+
".": {
173+
"types": "./dist/main.d.ts",
174+
"import": "./dist/rds.es.js",
175+
"require": "./dist/rds.umd.js"
176+
},
177+
"./dist/style.css": "./dist/style.css"
178+
}
179+
}
180+
```
181+
182+
### External Dependencies
183+
184+
All dependencies are externalized to avoid bundling:
185+
186+
```typescript
187+
external: [
188+
'react',
189+
'react-dom',
190+
'formik',
191+
'yup',
192+
'date-fns',
193+
'react-select',
194+
'react-player',
195+
'dompurify',
196+
'@react-google-maps/api',
197+
// ... etc
198+
]
199+
```
200+
201+
## Component Architecture
202+
203+
### Standard Component Structure
204+
205+
```
206+
ComponentName/
207+
├── ComponentName.tsx # Main component
208+
├── ComponentName.stories.tsx # Storybook stories
209+
├── styles.css # Component-scoped styles
210+
└── [SubComponents.tsx] # Optional sub-components
211+
```
212+
213+
### Composite Component Pattern
214+
215+
Complex components use `Object.assign` for sub-component attachment:
216+
217+
```typescript
218+
// Card.tsx
219+
const CardWrapper = ({ children, ...props }) => (
220+
<div {...props}>{children}</div>
221+
)
222+
223+
export const Card = Object.assign(CardWrapper, {
224+
Figure: CardFigure,
225+
Header: CardHeader,
226+
Body: CardBody,
227+
Content: CardContent,
228+
Footer: CardFooter,
229+
// ... more subcomponents
230+
})
231+
```
232+
233+
**Usage:**
234+
```tsx
235+
<Card>
236+
<Card.Figure src="/image.jpg" />
237+
<Card.Body>
238+
<Card.Header title="Card Title" />
239+
<Card.Content>Content here</Card.Content>
240+
</Card.Body>
241+
</Card>
242+
```
243+
244+
### TypeScript Patterns
245+
246+
**Props Interface Pattern:**
247+
```typescript
248+
export interface ButtonProps extends React.ComponentPropsWithoutRef<'button'> {
249+
color?: 'red' | 'grey' | 'dark-grey' | 'black' | 'white'
250+
isSmall?: boolean
251+
isFull?: boolean
252+
isDisabled?: boolean
253+
}
254+
```
255+
256+
**Discriminated Union Pattern:**
257+
```typescript
258+
// Button with title
259+
interface ButtonTitleProps extends BaseButtonProps {
260+
title: string
261+
children?: never
262+
}
263+
264+
// Button with children
265+
interface ButtonChildrenProps extends BaseButtonProps {
266+
children: React.ReactNode
267+
title?: never
268+
}
269+
270+
type ButtonProps = ButtonTitleProps | ButtonChildrenProps
271+
```
272+
273+
### Context Providers
274+
275+
**LinkProvider** for customizable link components:
276+
277+
```typescript
278+
// LinkContext.tsx
279+
export const LinkContext = createContext<React.ElementType>('a')
280+
export const useLinkContext = () => useContext(LinkContext)
281+
282+
// Usage in component
283+
const Link = useLinkContext()
284+
return <Link href={url}>{children}</Link>
285+
286+
// App-level customization
287+
import { Link } from 'next/link'
288+
<LinkProvider value={Link}>
289+
<App />
290+
</LinkProvider>
291+
```
292+
293+
## Dependency Management
294+
295+
### Peer Dependencies
296+
297+
```json
298+
{
299+
"peerDependencies": {
300+
"react": "^19.2.0",
301+
"react-dom": "^19.2.0"
302+
}
303+
}
304+
```
305+
306+
### Key Runtime Dependencies
307+
308+
| Package | Version | Purpose |
309+
|---------|---------|---------|
310+
| `formik` | 2.4.9 | Form state management |
311+
| `yup` | 1.7.1 | Schema validation |
312+
| `date-fns` | 4.1.0 | Date utilities |
313+
| `react-select` | 5.10.2 | Enhanced select dropdown |
314+
| `react-player` | 3.4.0 | Video player |
315+
| `dompurify` | 3.3.1 | HTML sanitization |
316+
| `@react-google-maps/api` | 2.20.8 | Google Maps |
317+
318+
### Styling Dependencies
319+
320+
| Package | Purpose |
321+
|---------|---------|
322+
| `tailwindcss` | Utility CSS framework |
323+
| `rds-tailwind-theme` | Carleton custom theme preset |
324+
| `@tailwindcss/forms` | Form element styles |
325+
| `@tailwindcss/typography` | Prose styles |
326+
| `@tailwindcss/aspect-ratio` | Aspect ratio utilities |
327+
| `@tailwindcss/container-queries` | Container queries |
328+
329+
## Configuration Files
330+
331+
### TypeScript (`tsconfig.json`)
332+
333+
```json
334+
{
335+
"compilerOptions": {
336+
"target": "ES2020",
337+
"module": "ESNext",
338+
"moduleResolution": "bundler",
339+
"jsx": "react-jsx",
340+
"strict": true,
341+
"noImplicitAny": true,
342+
"strictNullChecks": true,
343+
"skipLibCheck": true,
344+
"noEmit": true
345+
}
346+
}
347+
```
348+
349+
### Tailwind (`tailwind.config.ts`)
350+
351+
```typescript
352+
export default {
353+
presets: [require('rds-tailwind-theme')],
354+
content: ['./lib/**/*.{tsx,ts,jsx,js}'],
355+
darkMode: 'selector', // .dark class-based
356+
// Theme extensions...
357+
}
358+
```
359+
360+
### ESLint (`eslint.config.mjs`)
361+
362+
- Flat config format (ESLint 9+)
363+
- TypeScript support
364+
- React/React Hooks rules
365+
- Prettier integration
366+
- Storybook plugin
367+
- Cypress plugin
368+
369+
### Prettier (`.prettierrc`)
370+
371+
```json
372+
{
373+
"trailingComma": "all",
374+
"tabWidth": 2,
375+
"semi": false,
376+
"singleQuote": true,
377+
"printWidth": 120,
378+
"bracketSpacing": true
379+
}
380+
```
381+
382+
## Areas for Improvement
383+
384+
### Current Issues
385+
386+
1. **Large bundle size** - CSS includes unused Tailwind utilities
387+
2. **No tree-shaking** - All components bundled together
388+
3. **Tight Tailwind coupling** - Hard to customize without Tailwind knowledge
389+
4. **Limited CSS isolation** - Global styles can leak
390+
391+
### Planned Improvements
392+
393+
1. **SCSS Migration** - Move to CSS modules for better isolation
394+
2. **Component-level exports** - Enable tree-shaking
395+
3. **CSS extraction** - Separate critical and non-critical CSS
396+
4. **Better TypeScript** - Stricter types for Gutenberg integration
397+
398+
See [MIGRATION.md](./MIGRATION.md) for the Tailwind to SCSS migration plan.

0 commit comments

Comments
 (0)