# @setu/components

A modern React component library built on **shadcn/ui** with **Fictoan compatibility layer** for seamless migration.

## ✨ Features

- 🎨 **Modern Design**: Built on shadcn/ui with Radix UI primitives
- 🔄 **Fictoan Compatible**: 100% backward compatibility with Fictoan props
- 🎯 **TypeScript First**: Full TypeScript support with comprehensive types
- 🌙 **Theme Support**: Built-in dark mode and custom theme support
- 📦 **Tree Shakable**: Optimized bundle size with selective imports
- ♿ **Accessible**: ARIA compliant with keyboard navigation

## 📊 Bundle Size

- **ESM**: 1,140.93 KB (226.49 KB gzipped)
- **CJS**: 513.03 KB (147.23 KB gzipped)
- **Types**: 338 Bytes (235 Bytes gzipped)
- **Total**: 1.58 MB (364.04 KB gzipped)
- **Compression**: 77.5%

## 🚀 Installation

```bash
npm install @setu/components
# or
yarn add @setu/components
# or
pnpm add @setu/components
```

## 📖 Quick Start

### 3. Add CSS Variables

- Create a `globals.css` file in your project (commonly under `src/styles/globals.css`).
- **Important:** We use Tailwind CSS v4 classes to enable theming for our components.
- Import your `globals.css` file in your main entry file (e.g., `app.tsx` or `main.tsx`).

Example css file :

```css
@import "@setu/components/styles.css";

// Make sure to import the default @setu/components globals.css file

:root {
    --background: oklch(1 0 0);
    --foreground: oklch(0.145 0 0);
    --primary: oklch(0.205 0 0);
    --primary-foreground: oklch(0.985 0 0);
    --secondary: oklch(0.97 0 0);
    --secondary-foreground: oklch(0.205 0 0);
}

.dark {
    --background: oklch(0.145 0 0);
    --foreground: oklch(0.985 0 0);
    --primary: oklch(0.922 0 0);
    --primary-foreground: oklch(0.205 0 0);
    --secondary: oklch(0.269 0 0);
    --secondary-foreground: oklch(0.985 0 0);
}
```

> 💡 **Tip:** For the latest theme variables, refer to the official [shadcn/ui themes](https://ui.shadcn.com/themes).

> **WARNING** : If you are facing an issue where the dark theme is overriding the light theme, follow these steps to resolve it:
>
> 1. **Install Tailwind CSS and PostCSS (if not already installed):**
>     ```sh
>     npm install @tailwindcss/postcss
>     ```
> 2. **Add the `@custom-variant` tag to your `globals.css` file**  
>    At the top of your `src/styles/globals.css`, add:
>     ```css
>     @custom-variant dark (&:where(.dark, .dark *));
>     ```
>     This ensures that dark mode styles are properly scoped and do not override the light theme unintentionally.
> 3. **Verify your theme variable definitions**  
>    Make sure your CSS variables for both light and dark themes are defined under the correct selectors, as shown in the `globals.css` reference:
>
>     ```css
>     :root {
>         /* Light theme variables */
>         --background: ...;
>         /* ... */
>     }
>
>     .dark {
>         /* Dark theme overrides */
>         --background: ...;
>         /* ... */
>     }
>     ```
>
> 4. **Restart your development server**  
>    After making these changes, restart your dev server to ensure the new configuration is applied.

### 4. Setup Theme Provider

1 **Import the ThemeProvider exported from @setu/components**

```tsx
import { ThemeProvider } from "@setu/components";
```

2. **Wrap your app’s root with ThemeProvider:**
    - Place it as high as possible in your component tree (usually in `App.tsx` or `main.tsx`).
    - You can customize the default theme and storage key as needed.

```tsx
import { ThemeProvider } from "@setu/components";
import YourApp from "./YourApp";

export default function App() {
    return (
        <ThemeProvider
            defaultTheme="setu-light" // Options: "setu-light", "setu-dark", "light", "dark"
            storageKey="my-app-theme" // Change this key if you want to namespace your theme preference
        >
            <YourApp />
        </ThemeProvider>
    );
}
```

4. **Restart your dev server** after making these changes to ensure the theme provider is applied.

**Attach to your repo:**

- Add the `ThemeProvider` setup to your `App.tsx` or main entry file.
- Make sure your CSS includes the correct theme variable definitions (see earlier section for `globals.css`).

> 💡 For advanced usage, you can customize the `defaultTheme` and `storageKey` props. The provider will always prioritize the user’s saved preference over the default.

---

### 5. Usage

```tsx
import { Button, Card, CardContent, Alert, Input, Badge } from "@setu/components";

function MyComponent() {
    return (
        <Card className="w-96">
            <CardContent className="p-6 space-y-4">
                <div className="space-y-2">
                    <h3 className="text-lg font-semibold">Welcome to @setu/components</h3>
                    <Badge variant="secondary">Ready to use</Badge>
                </div>

                <Alert>
                    <AlertTitle>Success!</AlertTitle>
                    <AlertDescription>Your changes have been saved.</AlertDescription>
                </Alert>

                <div className="space-y-2">
                    <Input placeholder="Enter your name" />
                    <Button variant="default" size="lg" className="w-full">
                        Click me
                    </Button>
                </div>
            </CardContent>
        </Card>
    );
}
```

> 💡 **Explore All Components**: Visit [ui.setu.co](https://ui.setu.co) to see the complete list of 50+ components with interactive demos, code examples, and detailed documentation.

## 🔄 Fictoan Migration

<!-- TODO : Attach Codemods integration as well -->

### Backward Compatibility

Keep your existing Fictoan code working unchanged:

```tsx
// Your existing Fictoan code works as-is!
<Button colour="blue" kind="primary">
  Legacy Button
</Button>

<Card margin="medium" padding="large" shadow-sm="soft">
  Legacy Card Content
</Card>
```

### Migration Strategy

1. **Phase 1: Drop-in Replacement**

    ```bash
    # Replace Fictoan import
    - import { Button } from 'fictoan-react';
    + import { Button } from '@setu/components';
    ```

2. **Phase 2: Enhanced APIs**

    ```tsx
    // Gradually adopt new props while keeping Fictoan props
    <Button
        colour="blue" // Fictoan prop (still works)
        variant="default" // New shadcn/ui prop
    >
        Hybrid Usage
    </Button>
    ```

3. **Phase 3: Full Migration**
    ```tsx
    // Complete transition to shadcn/ui API
    <Button variant="default" size="lg">
        Modern Button
    </Button>
    ```

## 🛠️ Development

### Prerequisites

- Node.js 18+
- npm/yarn/pnpm

### Contributions

We welcome contributions! Please follow the guidelines suggested by SetuHQ

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'feat: add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

#### Initialize the repo

```bash
git clone https://github.com/SetuHQ/setu-components.git
cd setu-components
yarn install

# For VS Code users (enables proper TypeScript/ESLint integration with Yarn PnP)
yarn dlx @yarnpkg/sdks vscode
```

### Scripts

```bash
# Development

# Enable Corepack and use Yarn 4 (run once)
corepack enable
corepack prepare yarn@4.9.4 --activate

# For IDE integration (run once)
yarn dlx @yarnpkg/sdks vscode

# Setup Git hooks (run once)
yarn setup-hooks

yarn dev             # Start Vite dev server
yarn storybook       # Start Storybook

# Building
yarn build           # Build for production
yarn preview         # Preview production build

# Quality
yarn lint            # Run ESLint
yarn type-check      # TypeScript checking
yarn test            # Run tests

# Analysis
npm run build:analyze # Bundle size analysis + build
npm run treeshake     # Tree-shaking verification

# Publishing
npm run prepublishOnly # Pre-publish checks
npm publish           # Publish to npm
```

## 🏗️ Architecture

```
setu-components/
├── src/                        # Source code
│   ├── components/            # React components
│   │   ├── ui/               # UI components (50+ components)
│   │   │   ├── __tests__/    # Component tests
│   │   │   ├── *.tsx         # Component implementations
│   │   │   └── *.stories.tsx # Storybook stories
│   │   ├── theme-provider.tsx # Theme context provider
│   │   └── index.ts          # Component exports
│   ├── lib/                  # Core utilities
│   │   ├── utils.ts          # Utility functions
│   │   └── fictoan-schema.ts # Fictoan compatibility mappings
│   ├── styles/               # Global styles
│   │   └── globals.css       # Base CSS + Tailwind + Themes
│   └── index.ts              # Main export
├── dev-server/               # Development server
│   ├── demos/                # Component demos (50+ demos)
│   └── components/           # Dev server components
├── .storybook/              # Storybook configuration
└── dist/                    # Built output
```

## 📚 Documentation

- [Storybook](http://ui.storybook.setu.co) - Component documentation
- [Theme System](#3-add-css-variables) - Design tokens and theming
- [Contributing](#contributions) - Development guidelines

## 📄 License

This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.

## 🔗 Links

- [SetuHQ](https://setu.co) - Main website
- [GitHub](https://github.com/SetuHQ/setu-components) - Source code
- [npm](https://www.npmjs.com/package/@setu/components) - Package registry
- [Issues](https://github.com/SetuHQ/setu-components/issues) - Bug reports & feature requests

## ⭐ Show your support

Give a ⭐️ if this project helped you!

---

Built with ❤️ by the [Setu team](https://setu.co)
