アーキテクチャ
CodeConnect Design Systemの技術スタック、アーキテクチャ設計、および設計判断について説明します。
技術スタック
デザインシステム (packages/design-system)
UI
- React 19
- TypeScript 5.7
- Radix UI (Headless UI)
スタイリング
- Tailwind CSS 4
- CSS変数
- class-variance-authority
ビルド
- tsup (高速バンドラー)
- style-dictionary 4.2
ドキュメント
- Storybook 8
- Astro 5
プロジェクト構成
packages/design-system/├── src/│ ├── components/ # UIコンポーネント│ ├── styles/│ ├── tokens/│ └── index.ts├── .storybook/└── tsup.config.tsコンポーネント設計原則
1. ディレクトリ構成
各コンポーネントは独自のディレクトリを持ちます:
Button/├── Button.tsx # コンポーネント本体├── useButton.tsx # カスタムフック(ロジック分離)└── Button.stories.tsx # Storybook重要な規則:
- ❌ コンポーネントディレクトリ内で
index.tsは使用禁止 - ✅ パッケージルート (
src/index.ts) のみ許可
2. コンポーネント実装パターン
すべてのコンポーネントは以下のパターンに従います:
import { forwardRef } from 'react'import { cva, type VariantProps } from 'class-variance-authority'import { useButton } from './useButton'
export const buttonVariants = cva(/* バリアント定義 */)
export interface ButtonProps extends HTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {}
export const Button = forwardRef<HTMLButtonElement, ButtonProps>( (props, ref) => { const buttonProps = useButton(props) return <button ref={ref} {...buttonProps} /> })
Button.displayName = 'Button'import { cn } from '../../utils/cn'import { type ButtonProps, buttonVariants } from './Button'
export function useButton({ className, variant, size, ...props }: ButtonProps) { return { className: cn(buttonVariants({ variant, size, className })), ...props, }}3. ロジック/UI分離
- UI層 (
Component.tsx): 表示のみ - ロジック層 (
useComponent.tsx): スタイル、状態、副作用
4. class-variance-authority (CVA)
バリアント管理にCVAを使用:
export const buttonVariants = cva( 'base-classes', // 共通クラス { variants: { variant: { primary: 'primary-classes', secondary: 'secondary-classes', }, size: { sm: 'small-classes', md: 'medium-classes', }, }, defaultVariants: { variant: 'primary', size: 'md', }, })デザイントークン管理
style-dictionary
すべてのデザイントークンはstyle-dictionaryで一元管理:
{ "color": { "brand": { "base": { "value": "#1c71b9" } } }}自動生成されるCSS変数:
/* 自動生成 */:root { --color-brand-base: #1c71b9;}Tailwind CSS 4の@themeディレクティブで参照:
/* app.css など */@import "tailwindcss";@import "@codeconnect-llc/design-system/styles";
@theme { --color-brand: var(--color-brand-base);}Radix UI採用方針
なぜRadix UIか?
複雑なコンポーネントにはRadix UIを使用:
- ✅ アクセシビリティが完璧に実装済み
- ✅ キーボードナビゲーション対応
- ✅ フォーカス管理
- ✅ Headless(スタイルは自由)
採用コンポーネント
| コンポーネント | Radix UIパッケージ |
|---|---|
| Select | @radix-ui/react-select |
| Checkbox | @radix-ui/react-checkbox |
| RadioGroup | @radix-ui/react-radio-group |
| Switch | @radix-ui/react-switch |
| Dialog | @radix-ui/react-dialog |
| Toast | @radix-ui/react-toast |
| Tooltip | @radix-ui/react-tooltip |
自社実装コンポーネント
シンプルなコンポーネントは自社実装:
- Button, Card, Typography
- Input, Textarea
- Badge, Divider
- Box, Stack
モノレポ構成
pnpm Workspaces
すべてのパッケージを効率的に管理:
packages: - 'apps/*' - 'packages/*'依存関係
{ "dependencies": { "@codeconnect-llc/design-system": "workspace:*" }}ビルドシステム
tsup
高速なTypeScriptバンドラー:
export default defineConfig({ entry: ['src/index.ts'], format: ['esm', 'cjs'], dts: true, clean: true,})style-dictionary
トークン生成:
pnpm --filter @codeconnect/design-tokens build出力:
build/web/tokens.css- CSS変数build/ts/tokens.ts- TypeScript定数build/native/tokens.ts- React Native用
開発ツール
Biome
Linter & Formatter:
- シングルクォート
- セミコロンなし
- スペース2つインデント
- 行幅100文字
TypeScript
Strict Mode有効:
{ "compilerOptions": { "strict": true, "noUncheckedIndexedAccess": true, "noImplicitOverride": true }}設計判断の理由
なぜTailwind CSS 4?
- デザイントークンとの統合
- CSS変数ネイティブサポート
- ビルド時の最適化
- 開発体験の向上
パフォーマンス
バンドルサイズ最適化
- Tree-shaking対応
- ESM/CJS両対応
- 個別コンポーネントインポート可能
ランタイムパフォーマンス
- React 19の最新機能
- memo化の適切な使用
- レンダリング最適化
今後の展開
Phase 3: CMS統合
- Sanity CMS導入
- コンテンツ管理の柔軟化
Phase 4: 機能追加
- 検索機能
- 多言語対応
- ダークモード