@decidrcn/ui
v1.0.34
Published
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.
Downloads
106
Maintainers
Readme
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
npm install @decidrcn/ui
# or
yarn add @decidrcn/ui
# or
pnpm add @decidrcn/uiFor Rails Applications1 Add to your Gemfile:
gemjsbundling-rails
gem cssbundling-rails'
```2nstall the package:**
```bash
yarn add @decidrcn/ui
# or
npm install @decidrcn/ui- Configure your build tool (esbuild, webpack, or Vite):
With esbuild:
// 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:
// 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']
}
}
})4Import styles in your application:
// app/javascript/application.js
import '@decidrcn/ui/styles'Usage
React/Next.js Quick Start
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:**
// 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:**
# 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/ 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
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:
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
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
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
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.js2. 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:
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
pnpm storybookThis will start Storybook on `http://localhost:66re you can explore all components, including the Decidr logo.
Building
pnpm buildTesting
pnpm testContributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
Third-Party Licenses & Attribution
This package is built with and depends on:
Both projects are licensed under the MIT License.
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
