npm package: @srekaravarshan.dev/feather
Description: Tree-shakable React component library with vanilla-extract
Author: Sparrow Engineering
Latest version: 0.1.0

# @sparrowengg/feather

A tree-shakable React component library built with vanilla-extract for optimal bundle sizes.

## Features

- 🌲 **Tree-shakable** - Import only what you need
- 📦 **Tiny bundles** - Each component is separately compiled
- 🎨 **vanilla-extract** - Zero-runtime CSS with static extraction
- 🔷 **TypeScript** - Full type safety
- ⚡ **Fast** - Build-time CSS with no runtime overhead
- 🧪 **Well tested** - Comprehensive test coverage

## Installation

```bash
npm install @sparrowengg/feather
# or
yarn add @sparrowengg/feather
# or
pnpm add @sparrowengg/feather
```

## Peer Dependencies

Make sure you have React 18+ installed:

```bash
npm install react react-dom
```

## Usage

### Setup (Required)

**All Feather components require the `FeatherThemeProvider` wrapper.** This applies the theme CSS variables needed by all components:

```tsx
import { FeatherThemeProvider } from '@sparrowengg/feather/theme';
import { Button } from '@sparrowengg/feather/button';

function App() {
  return (
    <FeatherThemeProvider>
      <Button variant="solid" size="md">Click me</Button>
    </FeatherThemeProvider>
  );
}
```

### Importing Components

Import components individually for optimal tree-shaking:

```tsx
import { Button } from '@sparrowengg/feather/button';
import { Toast } from '@sparrowengg/feather/toast';
import { Tooltip } from '@sparrowengg/feather/tooltip';
```

### Theme Customization

Feather uses vanilla-extract for styling, which means you can create custom themes at build time using `createTheme`:

**Step 1: Create your custom theme** (in your app, e.g., `app/theme.css.ts`):

```tsx
import { createTheme } from '@vanilla-extract/css';
import { vars } from '@sparrowengg/feather/theme';

export const myAppTheme = createTheme(vars, {
  font: {
    body: 'Inter, system-ui, sans-serif',
    heading: 'Inter, system-ui, sans-serif',
    theme: 'Inter, system-ui, sans-serif',
  },
  colors: {
    primary: {
      500: '#0066cc',
      600: '#0052a3',
      // ... customize other shades as needed
    },
  },
  // Override any other tokens as needed
});
```

**Step 2: Apply your theme using `FeatherThemeProvider`**:

```tsx
import { FeatherThemeProvider } from '@sparrowengg/feather/theme';
import { myAppTheme } from './theme.css';

function App() {
  return (
    <FeatherThemeProvider themeClass={myAppTheme}>
      <YourApp />
    </FeatherThemeProvider>
  );
}
```

**Benefits of this approach:**
- ✅ **100% static CSS** - No runtime overhead
- ✅ **Type-safe** - Full TypeScript support for all theme tokens
- ✅ **Tree-shakable** - Only the styles you use are included
- ✅ **Scoped** - Multiple themes can coexist in the same app
- ✅ **Optimized bundles** - Theme CSS is loaded once, not duplicated per component (~35KB savings)

## Components

### Button

A versatile button component with multiple variants and sizes.

```tsx
import { Button, IconButton } from '@sparrowengg/feather/button';
import '@sparrowengg/feather/button.css';

// Basic button
<Button>Click me</Button>

// With variants
<Button variant="solid">Solid</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="outline">Outline</Button>

// With sizes
<Button size="xs">Extra Small</Button>
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>

// With colors
<Button color="primary">Primary</Button>
<Button color="default">Default</Button>

// Icon button
<IconButton icon={<Icon />} aria-label="Action" />
<IconButton icon={<Icon />} shape="round" aria-label="Round" />

// With states
<Button disabled>Disabled</Button>
<Button loading>Loading</Button>
```

**Props:**
- `variant`: `'solid' | 'ghost' | 'outline'` (default: `'solid'`)
- `size`: `'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'` (default: `'sm'`)
- `color`: `'default' | 'primary' | 'secondary' | 'bright' | 'light' | 'error' | 'none'` (default: `'primary'`)
- `disabled`: `boolean`
- `loading`: `boolean`
- `leftIcon`: `ReactElement`
- `rightIcon`: `ReactElement`
- `icon`: `ReactElement` (for icon-only buttons)

### Popover

A popover component with smart positioning.

```tsx
import { Popover, PopoverTrigger, PopoverContent } from '@sparrowengg/feather/popover';
import '@sparrowengg/feather/popover.css';

<Popover>
  <PopoverTrigger>
    <button>Open Popover</button>
  </PopoverTrigger>
  <PopoverContent className="your-styles">
    <div>Popover content goes here</div>
  </PopoverContent>
</Popover>

// With custom trigger
<Popover>
  <PopoverTrigger asChild>
    <Button>Custom Trigger</Button>
  </PopoverTrigger>
  <PopoverContent>Content</PopoverContent>
</Popover>
```

**Features:**
- Automatic positioning
- Click outside to close
- Portal rendering
- Scroll and resize aware

### Toast

A toast notification system.

```tsx
import { toast, ToastContainer } from '@sparrowengg/feather/toast';
import '@sparrowengg/feather/toast.css';

// Add ToastContainer to your app root
function App() {
  return (
    <>
      <YourApp />
      <ToastContainer />
    </>
  );
}

// Show toasts anywhere in your app
toast({ message: 'Success!', variant: 'success' });
toast({ message: 'Error occurred', variant: 'error' });
toast({ message: 'Warning!', variant: 'warning' });
toast({ message: 'Info message', variant: 'info' });
```

**Features:**
- Auto-dismiss after 5 seconds
- Multiple toasts support
- Portal rendering
- Variant-based styling

### Tooltip

A tooltip component with smart positioning and animations.

```tsx
import { Tooltip, TooltipProvider } from '@sparrowengg/feather/tooltip';
import '@sparrowengg/feather/tooltip.css';

// Wrap your app with TooltipProvider
function App() {
  return (
    <TooltipProvider>
      <YourApp />
    </TooltipProvider>
  );
}

// Use tooltips
<Tooltip content="This is a tooltip">
  <button>Hover me</button>
</Tooltip>

// With positioning
<Tooltip content="Top tooltip" side="top">
  <button>Hover me</button>
</Tooltip>

<Tooltip content="Right tooltip" side="right" align="start">
  <button>Hover me</button>
</Tooltip>

// With custom delay
<Tooltip content="Delayed tooltip" delayDuration={1000}>
  <button>Hover me</button>
</Tooltip>

// Disabled tooltip
<Tooltip content="Won't show" disabled>
  <button>Hover me</button>
</Tooltip>
```

**Props:**
- `content`: `ReactNode` - Tooltip content
- `side`: `'top' | 'bottom' | 'left' | 'right'` (default: `'top'`)
- `align`: `'start' | 'center' | 'end'` (default: `'center'`)
- `sideOffset`: `number` (default: `8`)
- `alignOffset`: `number` (default: `0`)
- `disabled`: `boolean` (default: `false`)
- `delayDuration`: `number` - Override provider delay

**TooltipProvider Props:**
- `delayDuration`: `number` (default: `700`) - Initial hover delay
- `skipDelayDuration`: `number` (default: `300`) - Time window to skip delay when switching tooltips

## Bundle Size

Each component is optimized for minimal bundle size:

| Component | JS (gzipped) | CSS (gzipped) |
|-----------|--------------|---------------|
| Button    | ~3-5 KB      | ~1-2 KB       |
| Popover   | ~2-3 KB      | ~0.5 KB       |
| Toast     | ~2-3 KB      | ~1 KB         |
| Tooltip   | ~4-5 KB      | ~1-2 KB       |

**Tree-shaking works!** Only import what you use:

```tsx
// ✅ Good - Only Button code is bundled
import { Button } from '@sparrowengg/feather/button';

// ❌ Avoid - Would bundle everything (if barrel export existed)
// import { Button } from '@sparrowengg/feather';
```

## Development

```bash
# Install dependencies
pnpm install

# Build the package
pnpm build

# Run tests
pnpm test

# Run tests in watch mode
pnpm test:watch

# Generate coverage report
pnpm test:coverage
```

### Code Quality

```bash
# Full quality check (typecheck + lint + knip + test)
pnpm check

# Type check
pnpm tscheck

# Lint and format check
pnpm lint

# Lint and format fix
pnpm fix

# Check for unused code, styles, and dependencies
pnpm knip

# Full analysis (knip + typecheck)
pnpm analyze
```

### Linting & Formatting

This package uses [Biome](https://biomejs.dev/) for fast linting and formatting:

```bash
# Check code (lint + format)
pnpm lint

# Auto-fix issues
pnpm lint:fix

# Format code
pnpm format

# Check formatting only
pnpm format:check
```

## Project Structure

```
packages/feather/
├── src/
│   ├── button/
│   │   ├── button.tsx
│   │   ├── button.css.ts        # vanilla-extract styles
│   │   ├── icon-button.tsx
│   │   ├── icon-button.css.ts   # vanilla-extract styles
│   │   ├── utils.ts
│   │   └── index.tsx
│   ├── popover/
│   ├── toast/
│   ├── tooltip/
│   └── theme/
│       ├── theme.css.ts         # Design tokens
│       └── utils.ts
├── tests/
│   ├── button.test.tsx
│   ├── popover.test.tsx
│   ├── toast.test.tsx
│   └── tooltip.test.tsx
├── dist/           # Built files (JS + extracted CSS)
└── package.json
```

## Contributing

Contributions are welcome! Please read our contributing guidelines before submitting a PR.

## License

MIT © Sparrow Engineering

## Support

For issues and feature requests, please use [GitHub Issues](https://github.com/sparrowengg/feather/issues).