Skip to main content

🧱 Part 12 — Storybook for React + TypeScript (Document & Test Your UI) 📚


Now that we have design system primitives (Button, Input, Card), we need a way to document, preview, and test them in isolation. That’s where Storybook comes in.

Storybook provides:

  • A component playground outside your app.
  • Interactive docs for your design system.
  • Addons for accessibility (a11y), viewport testing, and interaction testing.

1) Install Storybook

Run the official setup tool:

npx storybook@latest init
  • Detects React + TypeScript + Vite automatically.
  • Creates a .storybook/ folder with config.
  • Adds example stories in src/stories/.

Start Storybook:

pnpm storybook

This launches on http://localhost:6006.


2) Configure TypeScript support

In .storybook/tsconfig.json, extend your root config:

{
  "extends": "../tsconfig.json",
  "include": ["../src", "./*.ts", "./*.tsx"]
}

3) Write your first story (Button)

Stories live alongside components or in src/stories/. Each story is a different state of a component.

// src/components/ui/Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';

const meta: Meta<typeof Button> = {
  title: 'UI/Button',    // sidebar group
  component: Button,
  tags: ['autodocs'],    // enables auto docs
  argTypes: {
    onClick: { action: 'clicked' },
  },
};
export default meta;

// Story type
type Story = StoryObj<typeof Button>;

export const Primary: Story = {
  args: {
    children: 'Save',
    variant: 'primary',
  },
};

export const Secondary: Story = {
  args: {
    children: 'Cancel',
    variant: 'secondary',
  },
};

export const Danger: Story = {
  args: {
    children: 'Delete',
    variant: 'danger',
  },
};

Now you can toggle between Primary, Secondary, and Danger in Storybook.


4) Input story with error state

// src/components/ui/Input.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Input } from './Input';

const meta: Meta<typeof Input> = {
  title: 'UI/Input',
  component: Input,
  tags: ['autodocs'],
};
export default meta;

type Story = StoryObj<typeof Input>;

export const Default: Story = {
  args: {
    label: 'Email',
    placeholder: 'you@example.com',
  },
};

export const WithError: Story = {
  args: {
    label: 'Email',
    placeholder: 'you@example.com',
    error: 'Invalid email address',
  },
};

5) Card story

// src/components/ui/Card.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Card } from './Card';

const meta: Meta<typeof Card> = {
  title: 'UI/Card',
  component: Card,
  tags: ['autodocs'],
};
export default meta;

type Story = StoryObj<typeof Card>;

export const Default: Story = {
  args: {
    children: <p>This is a card with content.</p>,
  },
};

6) Useful addons

Install a few must-haves:

pnpm add -D @storybook/addon-a11y @storybook/addon-viewport @storybook/addon-interactions

Update .storybook/main.ts:

export default {
  addons: [
    '@storybook/addon-a11y',
    '@storybook/addon-viewport',
    '@storybook/addon-interactions'
  ],
};
  • a11y → accessibility checks in panel.
  • viewport → test responsive breakpoints.
  • interactions → simulate clicks/keyboard.

7) Why Storybook matters

  • Designers & devs share a living component library.
  • Test edge cases without spinning up the whole app.
  • Ensures your design system is documented.

✅ Wrap-Up

With Storybook:

  • Every component has isolated stories.
  • Docs update automatically when props/types change.
  • Addons give a11y audits, responsive previews, and interaction testing.

Comments

Popular posts from this blog

🌟 Dot net Microservices interview questions

Here is a comprehensive list of 200 .NET microservices coding questions covering all core microservices concepts and cross-cutting concerns relevant for designing, building, deploying, and maintaining .NET-based distributed systems. 🧩 A. Microservices Fundamentals (20) Build a microservice in .NET 8 that exposes a simple CRUD API. Implement communication between two microservices using REST. How would you design microservices for an e-commerce application? Create a microservice that handles user registration and login. How do you isolate domain logic in a microservice? How to apply the "Single Responsibility Principle" in microservices? Design a service registry/discovery mechanism using custom middleware. Implement a service that handles file uploads and metadata separately. Build a stateless microservice and explain its benefits. Implement health check endpoints in .NET 8. Demonstrate versioning in a microservice API. Add Swagger/OpenAPI support to your m...

⚡ Part 1: Introduction to Generics in C#

🌍 Why Do We Need Generics? Imagine you want to create a stack (like a pile of books 📚): You can push items on top You can pop items off the top If we write a stack for integers : public class IntStack { private int[] items = new int[10]; private int index = 0; public void Push(int item) => items[index++] = item; public int Pop() => items[--index]; } 👉 Problem: This only works for int . What if we want a string stack ? Or a Customer stack ? We’d have to duplicate code for every type. 😢 ✅ Solution: Generics Generics let us create type-safe reusable code without duplication. We can say: “I don’t care what type it is yet — I’ll decide later.” 1) Generic Classes Here’s a generic stack : // Generic class "Stack<T>" // The <T> is a placeholder for any type public class Stack<T> { private T[] items = new T[10]; // Array of type T private int index = 0; // Push adds an item of type T public void P...

🚪 Part 9: API Gateway for .NET 8 Microservices (Ocelot & YARP)

Once you have multiple microservices (Products, Orders, Payments…), exposing each one directly to clients gets messy: Different base URLs Duplicated auth logic No unified rate limiting / caching Hard to evolve routes or aggregate data 👉 Enter the API Gateway — your single front door for all microservices. An API Gateway handles: ✅ Routing & path rewriting ✅ Load balancing, retries, circuit breakers ✅ Authentication & Authorization (JWT, OAuth2) ✅ Rate limiting & caching ✅ Aggregation (compose results from multiple services) In this post we’ll implement two strong options: Ocelot → config-driven, mature, DevOps-friendly YARP (Yet Another Reverse Proxy) → Microsoft’s code-first, extensible gateway ⚖️ Ocelot vs YARP — When to Choose Ocelot → JSON config, minimal C#, built-in QoS (rate limit, circuit breaker). Perfect for teams that like DevOps config-as-code. YARP → full C# control, middleware-friendly, can embed into broader apps (e.g. add dashb...