Skip to content
Open
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
111 changes: 111 additions & 0 deletions docs/MIGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Migration Guide

Human-readable migration instructions for Stellar Dev Dashboard component library changes.
The interactive version with before/after code examples lives in Storybook:
**Design System / Migration**.

Full changelog: `docs/api/CHANGELOG.md`.

---

## Version History

### v0.1.0 (June 2025) — Initial Release

First public release. No migration required.

**Added:**
- Dashboard shell: Sidebar, MobileHeader, MobileSidebar, DashboardGrid
- Core components: Card, StatCard, CopyableValue, ThemeToggle
- Chart suite: NetworkMetricsChart, BalanceHistoryChart, AccountActivityChart
- Accessibility: AccessibilitySettings, ScreenReaderAnnouncer, KeyboardNavigation
- Network: NetworkIndicator, OfflineBanner, RetryButton
- Assets: AssetCard, AssetDiscovery
- Forms: ValidatedInput
- Design system: tokens, colors, spacing, typography, variants
- Storybook 8.5 with a11y, viewport addons, and dark/light theme toolbar

---

## Breaking Changes

No breaking changes in v0.1.0.

Future breaking changes will be documented here with migration steps and, where possible,
a codemod command.

---

## Active Migration Tracks

### JavaScript → TypeScript

The codebase is migrating from `.jsx` to `.tsx`. New components **must** be TypeScript.

**Steps for converting an existing component:**

1. Rename the file from `.jsx` to `.tsx`.
2. Add prop types using interfaces from `src/types/components.ts` where they exist.
3. Run `npm run type-check` to surface type errors.
4. Fix errors — the `tsconfig.json` has `allowJs: true` so no config changes are needed.
5. Update any `.stories.tsx` imports if the file extension changed.

```ts
// src/types/components.ts — add your interface
export interface MyComponentProps {
title: string;
onAction?: () => void;
}

// src/components/dashboard/MyComponent.tsx
import type { MyComponentProps } from '../../types/components';

export default function MyComponent({ title, onAction }: MyComponentProps) { … }
```

---

### Inline Styles → CSS Custom Properties

Components should use `var(--token)` rather than hard-coded hex values.

```jsx
// ❌ Before
<div style={{ color: '#f8fafc', background: '#0f172a' }}>

// ✅ After
<div style={{ color: 'var(--text-primary)', background: 'var(--bg-card)' }}>
```

Reference the full token list in `docs/design-system.md` or the **Design System / Tokens**
Storybook story.

Do **not** remove legacy token aliases until all call sites are migrated.

---

### Adopting the Variant System

New component variants should live in `src/design-system/variants.ts`, not as ad-hoc inline
style objects scattered across component files.

```ts
// src/design-system/variants.ts — add to the relevant group
{
key: 'ghost',
label: 'Ghost',
description: 'Transparent background, border only. For tertiary actions.',
composition: ['border.default', 'text.primary', 'radii.sm'],
status: 'planned', // → 'ready' once implemented
}
```

---

## Adding a Breaking Change (for maintainers)

1. Add to `docs/api/CHANGELOG.md` under `## Breaking Changes` for the next version.
2. Add a migration entry to `stories/Migration.stories.tsx`.
3. If automatable, provide a codemod: `npx codemod <package-name>`.
4. Keep legacy aliases active for at least one minor version before removing them.
5. Update this document.
124 changes: 124 additions & 0 deletions docs/PERFORMANCE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# Component Performance Guide

Reference for component render budgets, bundle size targets, and optimization patterns.
The interactive version of this guide lives in Storybook: **Design System / Performance**.

---

## Build Budget

| Metric | Target | Enforcement |
|--------|--------|-------------|
| Total bundle (gzipped) | ≤ 500 KB | `scripts/check-coverage.mjs` in CI |
| Lighthouse Performance | ≥ 90 | `npm run test:lighthouse` |
| LCP (largest contentful paint) | < 2.5 s | Lighthouse CI |
| CLS (cumulative layout shift) | < 0.1 | Playwright visual tests |

---

## Bundle Size by Component Group

| Component | Gzipped | Notes |
|-----------|---------|-------|
| Card / StatCard | ~1 KB | Inline styles only |
| CopyableValue | ~1 KB | Single clipboard effect |
| ThemeToggle | ~2 KB | lucide-react icon + Zustand read |
| NetworkIndicator | ~2 KB | Pure display |
| ValidatedInput | ~3 KB | Self-contained validation |
| BottomSheet | ~4 KB | `useResponsive` + touch gestures |
| ResponsiveContainer | ~4 KB | Three exported components |
| AssetCard | ~3 KB | No chart deps |
| NetworkMetricsChart | ~8 KB | Recharts (shared chunk) |
| BalanceHistoryChart | ~6 KB | Recharts (shared chunk) |
| TransactionBuilder | ~28 KB | stellar-sdk; **must be lazy-loaded** |
| ContractInteraction | ~24 KB | soroban-client; **must be lazy-loaded** |
| D3VisualizationSuite | ~35 KB | Full D3 force graph; **lazy-loaded on demand** |

---

## Render Time Targets

| Category | Budget | Examples |
|----------|--------|---------|
| Pure UI components | < 1 ms | Card, StatCard, CopyableValue, ThemeToggle, ValidatedInput |
| Layout components | < 5 ms | Sidebar, MobileHeader, BottomSheet, ResponsiveContainer |
| Chart components | < 50 ms | NetworkMetricsChart, BalanceHistoryChart |
| Feature panels (API-dependent) | < 100 ms to first paint | Overview, Account, Transactions |
| Heavy editors | < 200 ms after lazy load | TransactionBuilder, ContractInteraction |

---

## Optimization Patterns

### 1. Code Split Heavy Components

```jsx
// ✅ Required for any component > 10 KB
const TransactionBuilder = React.lazy(() =>
import('./components/dashboard/TransactionBuilder')
);

<Suspense fallback={<div className="spinner" />}>
<TransactionBuilder />
</Suspense>
```

### 2. Virtualize Long Lists

`src/components/common/VirtualList.jsx` is available for lists with > 50 items.

```jsx
import VirtualList from './components/common/VirtualList';

<VirtualList
items={transactions}
itemHeight={52}
renderItem={(tx) => <TransactionRow tx={tx} />}
/>
```

### 3. Memoize Stable References

Only memoize after profiling confirms a performance problem.

```jsx
const chartData = useMemo(
() => buildChartSeries(rawLedgers),
[rawLedgers]
);
```

### 4. Debounce Live Queries

```jsx
const debouncedQuery = useDebounce(query, 300);

useEffect(() => {
if (debouncedQuery) fetchAssets(debouncedQuery);
}, [debouncedQuery]);
```

### 5. Respect prefers-reduced-motion

```jsx
const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const duration = prefersReduced ? 0 : tokens.motion.duration.normal;
```

The `AccessibilityContext` exposes a `reducedMotion` flag — use it in components
rather than reading the media query directly.

---

## Profiling

```bash
# Lighthouse CI (requires a local build)
npm run test:lighthouse

# Bundle analysis
npm run build:analyze

# Vitest coverage
npm run test:coverage
```
Loading
Loading