npm package: @decidrcn/ui
Description: Decidr UI - A comprehensive React component library built with shadcn/ui and Radix UI. Supports React, Next.js, Rails, and works with npm, yarn, and pnpm.
Author: Decidr Team
Latest version: 1.0.34

# Decidr UI

A comprehensive React component library built with shadcn/ui and Radix UI, designed for modern web applications including Rails apps using Slim templates.

---

## Monorepo Structure

This project uses a **pnpm monorepo** structure:

- **Root**: Manages workspace dependencies and scripts
- **packages/ui**: The Decidr UI component library (this package)
- **apps/demo**: Demo app to showcase components

All packages now use **React 19** for consistency and future-proofing.

---

## Features

- 🎨 **Beautiful Design**: Built on shadcn/ui with Tailwind CSS
- ♿ **Accessible**: Powered by Radix UI primitives
- 🎯 **Type Safe**: Full TypeScript support
- 🚀 **Fast**: Optimized for performance
- 🎪 **Customizable**: Extensive theming and customization options
- 📱 **Responsive**: Mobile-first design approach
- ⚛️ **React19 Ready**: Fully compatible with React19🛤️ **Rails Compatible**: Works seamlessly with Rails applications using Slim templates

---

## Installation

### For React/Next.js Applications

```bash
npm install @decidrcn/ui
# or
yarn add @decidrcn/ui
# or
pnpm add @decidrcn/ui
```

### For Rails Applications1 **Add to your Gemfile:**
```ruby
gemjsbundling-rails
gem cssbundling-rails'
```2nstall the package:**
```bash
yarn add @decidrcn/ui
# or
npm install @decidrcn/ui
```

3. **Configure your build tool (esbuild, webpack, or Vite):**

**With esbuild:**
```javascript
// config/esbuild.config.js
const esbuild = require('esbuild')

esbuild.build({
  entryPoints: ['app/javascript/application.js],
  bundle: true,
  outdir: app/assets/builds',
  format:esm,
  plugins: ],
  external: ['@decidrcn/ui']
})
```

**With Vite:**
```javascript
// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: react()],
  build: {
    rollupOptions:[object Object]      external: ['@decidrcn/ui']
    }
  }
})
```

4**Import styles in your application:**
```javascript
// app/javascript/application.js
import '@decidrcn/ui/styles'
```

---

## Usage

### React/Next.js Quick Start

```tsx
import { Button } from@decidrcn/ui;
function App() {
  return (
    <Button variant="default>
      Hello Decidr UI!
    </Button>
  );
}
```

### Rails with Slim Templates
1p React components in your Rails app:**

```javascript
// app/javascript/components/DecidrButton.jsx
import React from 'react'
import { Button } from '@decidrcn/ui'

export default function DecidrButton({ children, variant = 'default, ...props }) {
  return (
    <Button variant={variant}[object Object]...props}>
      {children}
    </Button>
  )
}
```2 in Slim templates:**

```slim
/ app/views/layouts/application.html.slim
doctype html
html
  head
    title My Rails App
    = csrf_meta_tags
    = csp_meta_tag
    = stylesheet_link_tag "application",data-turbo-track": "reload
    = javascript_importmap_tags

  body
    / Your content here
    = yield

/ app/views/pages/home.html.slim
.container
  h1 Welcome to My App
  
  / Using React components in Slim
  #react-button-container data-props={variant: 'gradient', children:Click me!'}
  
  / Or with more complex props
  #react-carousel-container data-props={products: @products.to_json}
```3t React components:**

```javascript
// app/javascript/application.js
import React from 'react'
import { createRoot } fromreact-dom/client'
import DecidrButton from./components/DecidrButton'
import ProductCarousel from './components/ProductCarousel'

// Mount components when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
  // Mount button component
  const buttonContainer = document.getElementById('react-button-container')
  if (buttonContainer)[object Object]
    const props = JSON.parse(buttonContainer.dataset.props || '{}')
    const root = createRoot(buttonContainer)
    root.render(React.createElement(DecidrButton, props))
  }

  // Mount carousel component
  const carouselContainer = document.getElementById('react-carousel-container')
  if (carouselContainer)[object Object]
    const props = JSON.parse(carouselContainer.dataset.props || '{}')
    const root = createRoot(carouselContainer)
    root.render(React.createElement(ProductCarousel, props))
  }
})
```

4d Slim integration with helpers:**

```ruby
# app/helpers/decidr_helper.rb
module DecidrHelper
  def decidr_button(text, variant: 'default', **options)
    content_tag :div, 
   , 
                id:decidr-button-#[object Object]SecureRandom.hex(4)},              data: { 
                  component: 'DecidrButton',
                  props: { 
                    children: text, 
                    variant: variant,
                    **options 
                  }.to_json 
                }
  end

  def decidr_carousel(items, **options)
    content_tag :div, 
   , 
                id: decidr-carousel-#[object Object]SecureRandom.hex(4)},              data: { 
                  component: 'ProductCarousel',
                  props: { 
                    products: items,
                    **options 
                  }.to_json 
                }
  end
end
```

```slim
/ Using helpers in Slim
.container
  = decidr_button "Submit Form", variant:gradient, size: lg"
  
  = decidr_carousel @products, opts: { loop: true }
```

---

## Components

### Button
Enhanced button component with support for:
- Multiple variants (default, secondary, destructive, outline, ghost, link, success, warning, info, gradient)
- Custom colors and gradients
- Icon support (left, right, or icon-only)
- Radius customization
- Multiple sizes
- Default variant: White background with black text
- Gradient variant: Beautiful gradient with full radius support

```tsx
import { Button } from '@decidrcn/ui';
import[object Object]PlusIcon } from '@radix-ui/react-icons;

// Basic usage (white background, black text)
<Button>Click me</Button>

// Gradient button with full radius
<Button variant="gradient radius=full
  Gradient Button
</Button>

// With custom colors
<Button bgColor="#8B5CF6 textColor="white hoverBgColor="#7C3AED>
  Purple Button
</Button>

// With icons
<Button leftIcon={<PlusIcon className="h-44/>}>
  Add Item
</Button>

// Icon only
<Button size=icon" leftIcon={<PlusIcon className="h-4 w-4>} />
```

### Carousel
Flexible carousel component perfect for products and events:

```tsx
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from @decidrcn/ui';

<Carousel className="w-full max-w-6  <CarouselContent>
    {products.map((product) => (
      <CarouselItem key={product.id} className=md:basis-1/2 lg:basis-1/3">
        <ProductCard product={product} />
      </CarouselItem>
    ))}
  </CarouselContent>
  <CarouselPrevious />
  <CarouselNext />
</Carousel>
```

### Avatar
Avatar component with shape variants:
- Circle (default)
- Square
- Rounded variants

```tsx
import { Avatar, AvatarFallback, AvatarImage } from @decidrcn/ui';

<Avatar shape="circle">
  <AvatarImage src="user.jpg" alt="User />
  <AvatarFallback>JD</AvatarFallback>
</Avatar>
```

### DecidrHeader
Semantic header component with proper text sizes for different heading levels:
- H1: Large title (text-4xl, font-bold)
- H2: Section header (text-3xl, font-semibold) 
- H3: Subsection header (text-2l, font-semibold)
- H4-H6aller headers with appropriate sizing

```tsx
import { DecidrHeader } from@decidrcn/ui';

// Different heading levels with automatic text sizing
<DecidrHeader as="h1>Main Page Title</DecidrHeader>
<DecidrHeader as=h2Section Title</DecidrHeader>
<DecidrHeader as="h3>Subsection Title</DecidrHeader>

// Custom styling
<DecidrHeader as="h2assName=text-blue-600>
  Custom Styled Header
</DecidrHeader>
```

### DecidrBody
Body text component with different size variants for optimal readability:
- xs: Extra small (text-xs) - Fine print, metadata
- sm: Small (text-sm) - Captions, secondary info
- base: Default (text-base) - Standard paragraphs
- lg: Large (text-lg) - Important content, emphasis
- xl: Extra large (text-xl) - Prominent content sections

```tsx
import { DecidrBody } from@decidrcn/ui';

// Different text sizes
<DecidrBody size="xl">Prominent content section</DecidrBody>
<DecidrBody size="lg">Important information</DecidrBody>
<DecidrBody size="base">Standard paragraph text</DecidrBody>
<DecidrBody size="sm">Secondary information</DecidrBody>
<DecidrBody size="xs">Fine print and metadata</DecidrBody>

// Different HTML elements
<DecidrBody as=span>Inline text</DecidrBody>
<DecidrBody as=div">Block text</DecidrBody>

// Custom styling
<DecidrBody size="lg" className="text-blue-600 italic>Custom styled body text
</DecidrBody>
```

---

## Rails Integration Best Practices

### 1. Component Organization
```
app/javascript/
├── components/
│   ├── decidr/
│   │   ├── DecidrButton.jsx
│   │   ├── DecidrCarousel.jsx
│   │   └── DecidrCard.jsx
│   └── shared/
└── application.js
```

### 2. Data Flow
- Pass data from Rails controllers to React components via `data-props`
- Use JSON serialization for complex objects
- Keep React components stateless when possible

### 3. Styling
- Import Decidr UI styles in your main application file
- Use Tailwind CSS classes in Slim templates
- Customize theme variables in your CSS

### 4Performance
- Lazy load React components when needed
- Use Turbo for fast page transitions
- Bundle components efficiently

---

## Decidr Logo

The Decidr logo is available as a React component:

```tsx
import { Logo } from @decidrcn/ui';

<Logo className="w-20 h-5 text-primary" />
```

- Used in Storybook and throughout the design system
- SVG-based, theme-aware (uses `currentColor`)
- Easily resizable and styleable

---

## Development

### Running Storybook

```bash
pnpm storybook
```

This will start Storybook on `http://localhost:66re you can explore all components, including the Decidr logo.

### Building

```bash
pnpm build
```

### Testing

```bash
pnpm test
```

---

## Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Submit a pull request

---

## Third-Party Licenses & Attribution

This package is built with and depends on:

- [shadcn/ui](https://github.com/shadcn-ui/ui) — MIT License © shadcn
- [Radix UI](https://www.radix-ui.com/) — MIT License © WorkOS, Inc.

Both projects are licensed under the [MIT License](https://opensource.org/licenses/MIT).  
Copies of their licenses are available in their respective repositories.

We thank the authors and contributors of these projects for their amazing work!

## License

MIT © Decidr Team