drover: Merge task-1767764907653950146

This commit is contained in:
Ubuntu
2026-01-10 05:38:15 +00:00
48 changed files with 8052 additions and 0 deletions

View File

@@ -0,0 +1,232 @@
# Leptos Shadcn UI - Component API Reference
Complete API documentation for all components in the leptos-shadcn-ui library.
---
## Table of Contents
- [Form Components](#form-components)
- [Layout Components](#layout-components)
- [Navigation Components](#navigation-components)
- [Overlay Components](#overlay-components)
- [Data Display & Feedback Components](#data-display--feedback-components)
- [Interactive Components](#interactive-components)
- [Utility Components](#utility-components)
---
## Form Components
### [Button](#button) | [Input](#input) | [Label](#label) | [Checkbox](#checkbox) | [Switch](#switch) | [Radio Group](#radio-group) | [Select](#select) | [Textarea](#textarea) | [Form](#form) | [Combobox](#combobox) | [Command](#command) | [Input OTP](#input-otp)
---
## Layout Components
### [Card](#card) | [Separator](#separator) | [Tabs](#tabs) | [Accordion](#accordion) | [Collapsible](#collapsible) | [Scroll Area](#scroll-area) | [Aspect Ratio](#aspect-ratio) | [Resizable](#resizable)
---
## Navigation Components
### [Breadcrumb](#breadcrumb) | [Navigation Menu](#navigation-menu) | [Context Menu](#context-menu) | [Dropdown Menu](#dropdown-menu) | [Menubar](#menubar)
---
## Overlay Components
### [Dialog](#dialog) | [Popover](#popover) | [Tooltip](#tooltip) | [Alert Dialog](#alert-dialog) | [Sheet](#sheet) | [Drawer](#drawer) | [Hover Card](#hover-card)
---
## Data Display & Feedback Components
### [Alert](#alert) | [Badge](#badge) | [Skeleton](#skeleton) | [Progress](#progress) | [Toast](#toast) | [Table](#table) | [Calendar](#calendar) | [Date Picker](#date-picker) | [Pagination](#pagination)
---
## Interactive Components
### [Slider](#slider) | [Toggle](#toggle) | [Carousel](#carousel) | [Avatar](#avatar)
---
## Utility Components
### [Error Boundary](#error-boundary) | [Lazy Loading](#lazy-loading) | [Registry](#registry)
---
## Detailed Component Documentation
Select a component below to view its complete API documentation:
- **[Button](./api/button.md)** - Interactive button with multiple variants and sizes
- **[Input](./api/input.md)** - Text input with validation support
- **[Dialog](./api/dialog.md)** - Modal dialog component
- **[Card](./api/card.md)** - Content container with header, body, and footer
- **[Tabs](./api/tabs.md)** - Tabbed content switcher
- **[Select](./api/select.md)** - Dropdown selection component
- **[Checkbox](./api/checkbox.md)** - Binary selection input
- **[Switch](./api/switch.md)** - Toggle switch component
- **[Radio Group](./api/radio-group.md)** - Single selection from options
- **[Textarea](./api/textarea.md)** - Multi-line text input
- **[Label](./api/label.md)** - Form label component
- **[Form](./api/form.md)** - Form container with validation
- **[Alert](./api/alert.md)** - Alert message display
- **[Badge](./api/badge.md)** - Status indicator badge
- **[Skeleton](./api/skeleton.md)** - Loading placeholder
- **[Progress](./api/progress.md)** - Progress indicator
- **[Toast](./api/toast.md)** - Temporary notification
- **[Table](./api/table.md)** - Data table display
- **[Separator](./api/separator.md)** - Visual divider
- **[Accordion](./api/accordion.md)** - Collapsible content sections
- **[Collapsible](./api/collapsible.md)** - Show/hide content toggle
- **[Scroll Area](./api/scroll-area.md)** - Custom scrollable container
- **[Aspect Ratio](./api/aspect-ratio.md)** - Fixed aspect ratio container
- **[Resizable](./api/resizable.md)** - Resizable panel layout
- **[Breadcrumb](./api/breadcrumb.md)** - Navigation breadcrumb
- **[Navigation Menu](./api/navigation-menu.md)** - Site navigation
- **[Context Menu](./api/context-menu.md)** - Right-click context menu
- **[Dropdown Menu](./api/dropdown-menu.md)** - Dropdown action menu
- **[Menubar](./api/menubar.md)** - Application menu bar
- **[Dialog](./api/dialog.md)** - Modal dialog
- **[Popover](./api/popover.md)** - Floating content container
- **[Tooltip](./api/tooltip.md)** - Hover information tip
- **[Alert Dialog](./api/alert-dialog.md)** - Confirmation dialog
- **[Sheet](./api/sheet.md)** - Side panel drawer
- **[Drawer](./api/drawer.md)** - Slide-out drawer
- **[Hover Card](./api/hover-card.md)** - Hover-triggered card
- **[Calendar](./api/calendar.md)** - Date picker calendar
- **[Date Picker](./api/date-picker.md)** - Date selection component
- **[Pagination](./api/pagination.md)** - Page navigation
- **[Slider](./api/slider.md)** - Range slider input
- **[Toggle](./api/toggle.md)** - Toggle button
- **[Carousel](./api/carousel.md)** - Image/content carousel
- **[Avatar](./api/avatar.md)** - User avatar display
- **[Combobox](./api/combobox.md)** - Searchable select
- **[Command](./api/command.md)** - Command palette
- **[Input OTP](./api/input-otp.md)** - One-time password input
- **[Error Boundary](./api/error-boundary.md)** - Error handling wrapper
- **[Lazy Loading](./api/lazy-loading.md)** - Lazy component loading
- **[Registry](./api/registry.md)** - Component registry
---
## Common Props Reference
Most components support these common props:
### Core Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `id` | `Option<String>` | `None` | Unique identifier for the component |
| `class` | `Option<String>` | `None` | Additional CSS classes |
| `style` | `Option<Style>` | `None` | Inline styles |
### Accessibility Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `aria_label` | `Option<String>` | `None` | Accessible name for screen readers |
| `aria_describedby` | `Option<String>` | `None` | ID of element describing this component |
| `aria_labelledby` | `Option<String>` | `None` | ID of element labeling this component |
| `role` | `Option<String>` | `None` | ARIA role override |
### State Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `disabled` | `Signal<bool>` | `false` | Disable component interaction |
| `readonly` | `Option<bool>` | `false` | Make component read-only |
---
## Variant System
Components support multiple visual variants:
### Button Variants
```rust
pub enum ButtonVariant {
Default,
Destructive,
Outline,
Secondary,
Ghost,
Link,
}
```
### Button Sizes
```rust
pub enum ButtonSize {
Default,
Sm,
Lg,
Icon,
}
```
---
## Theme Support
All components support two theme variants:
- **Default Theme** - Standard shadcn/ui styling
- **New York Theme** - Alternative design system
```rust
// Import Default theme
use shadcn_ui_leptos_button::Button;
// Import New York theme
use shadcn_ui_leptos_button::ButtonNewYork;
```
---
## Signal-Managed Components
Many components offer signal-managed variants with enhanced reactivity:
```rust
use shadcn_ui_leptos_button::SignalManagedButton;
// Provides built-in state management
let button_state = SignalManagedButtonState::new();
```
---
## TypeScript Definitions
TypeScript definitions are available for JavaScript/TypeScript interoperability:
```typescript
import { Button } from '@leptos-shadcn-ui/button';
interface ButtonProps {
variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link';
size?: 'default' | 'sm' | 'lg' | 'icon';
disabled?: boolean;
onClick?: () => void;
children?: React.ReactNode;
}
```
---
## Examples
See the [Example Usage Guide](./example-usage.md) for comprehensive examples of all components.
---
## Accessibility
All components follow WCAG 2.1 AA standards. See the [Accessibility Guide](./ACCESSIBILITY_GUIDE.md) for details.
---
*Last Updated: January 2026*
*Version: 0.7.0*

View File

@@ -0,0 +1,179 @@
# Accordion Component API
A vertically collapsible component for organizing content into expandable sections.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-accordion = "0.7"
```
```rust
use shadcn_ui_leptos_accordion::Accordion;
```
---
## Import
```rust
use shadcn_ui_leptos_accordion::{
Accordion,
AccordionItem,
AccordionTrigger,
AccordionContent
};
```
---
## Component API
### Accordion
Root container managing accordion state.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `Signal<String>` | **Required** | Currently open item |
| `on_change` | `Option<Callback<String>>` | `None` | Change handler |
| `multiple` | `Signal<bool>` | `false` | Allow multiple open |
| `collapsible` | `Signal<bool>` | `true` | Allow collapsing all |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
### AccordionItem
Individual accordion section.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `String` | **Required** | Item identifier |
| `disabled` | `Signal<bool>` | `false` | Disable item |
### AccordionTrigger
Clickable header for accordion item.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
### AccordionContent
Collapsible content area.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
---
## Usage Examples
### Basic Accordion
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_accordion::*;
#[component]
pub fn MyComponent() -> impl IntoView {
let (value, set_value) = signal("item-1".to_string());
view! {
<Accordion
value=value.into()
on_change=Some(Callback::new(move |v| set_value.set(v)))
>
<AccordionItem value="item-1">
<AccordionTrigger>"Is it accessible?"</AccordionTrigger>
<AccordionContent>
"Yes. It adheres to the WAI-ARIA design pattern."
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger>"Is it styled?"</AccordionTrigger>
<AccordionContent>
"Yes. It comes with default styles."
</AccordionContent>
</AccordionItem>
</Accordion>
}
}
```
---
## CSS Classes
```css
.accordion {
border-b
}
.accordion-item {
border-b
}
.accordion-trigger {
flex flex-1 items-center justify-between
py-4 font-medium transition-all
hover:underline [&[data-state=open]>svg]:rotate-180
}
.accordion-content {
overflow-hidden text-sm transition-all
}
.accordion-content[data-state=closed] {
animate-accordion-up
}
.accordion-content[data-state=open] {
animate-accordion-down
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Tab** | Navigate accordion |
| **Enter/Space** | Toggle section |
| **Arrow Down** | Next section |
| **Arrow Up** | Previous section |
| **Home** | First section |
| **End** | Last section |
---
## TypeScript API
```typescript
interface AccordionProps {
value: string;
onChange?: (value: string) => void;
multiple?: boolean;
collapsible?: boolean;
className?: string;
children?: React.ReactNode;
}
export const Accordion: React.FC<AccordionProps>;
export const AccordionItem: React.FC<{ value: string; disabled?: boolean }>;
export const AccordionTrigger: React.FC<ComponentProps>;
export const AccordionContent: React.FC<ComponentProps>;
```
---
*Source: [packages/leptos/accordion/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/accordion/src/default.rs)*

View File

@@ -0,0 +1,159 @@
# Alert Dialog Component API
A modal dialog for critical confirmations and destructive actions.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-alert-dialog = "0.7"
```
```rust
use shadcn_ui_leptos_alert_dialog::AlertDialog;
```
---
## Import
```rust
use shadcn_ui_leptos_alert_dialog::{
AlertDialog,
AlertDialogTrigger,
AlertDialogContent,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogCancel,
AlertDialogAction
};
```
---
## Component API
### AlertDialog
Root component managing dialog state.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `open` | `Signal<bool>` | **Required** | Open state |
| `on_open_change` | `Option<Callback<bool>>` | `None` | Change handler |
### AlertDialogAction
Primary action button (usually destructive).
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `on_click` | `Option<Callback<()>>` | `None` | Click handler |
### AlertDialogCancel
Cancel button that closes dialog.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `on_click` | `Option<Callback<()>>` | `None` | Click handler |
---
## Usage Examples
### Basic Alert Dialog
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_alert_dialog::*;
#[component]
pub fn DeleteConfirmation() -> impl IntoView {
let (open, set_open) = signal(false);
view! {
<AlertDialog
open=open.into()
on_open_change=Some(Callback::new(move |v| set_open.set(v)))
>
<AlertDialogTrigger>
<button class="text-destructive">"Delete Account"</button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>"Are you sure?"</AlertDialogTitle>
<AlertDialogDescription>
"This action cannot be undone. This will permanently \
delete your account and remove all data."
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>"Cancel"</AlertDialogCancel>
<AlertDialogAction on_click=Some(Callback::new(move |_| {
// Perform deletion
set_open.set(false);
}))>
"Delete"
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
}
}
```
---
## CSS Classes
```css
.alert-dialog-content {
fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg
translate-x-[-50%] translate-y-[-50%] gap-4 border
bg-background p-6 shadow-lg duration-200
}
.alert-dialog-action {
bg-destructive text-destructive-foreground
hover:bg-destructive/90
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Escape** | Close dialog |
| **Enter** | Confirm action (when focused) |
---
## TypeScript API
```typescript
interface AlertDialogProps {
open: boolean;
onOpenChange?: (open: boolean) => void;
children?: React.ReactNode;
}
export const AlertDialog: React.FC<AlertDialogProps>;
export const AlertDialogTrigger: React.FC<ComponentProps>;
export const AlertDialogContent: React.FC<ComponentProps>;
export const AlertDialogAction: React.FC<ButtonProps>;
export const AlertDialogCancel: React.FC<ButtonProps>;
```
---
*Source: [packages/leptos/alert-dialog/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/alert-dialog/src/default.rs)*

View File

@@ -0,0 +1,195 @@
# Alert Component API
A component for displaying alert messages with different severity levels.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-alert = "0.7"
```
```rust
use shadcn_ui_leptos_alert::Alert;
```
---
## Import
```rust
use shadcn_ui_leptos_alert::{
Alert,
AlertTitle,
AlertDescription,
AlertVariant
};
```
---
## Component API
### Alert
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `variant` | `MaybeProp<AlertVariant>` | `Default` | Alert style variant |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Alert content |
### AlertVariant
```rust
pub enum AlertVariant {
Default, // Neutral styling
Destructive, // Red for errors
Warning, // Yellow for warnings
Info, // Blue for information
Success, // Green for success
}
```
### AlertTitle
Title text for the alert.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Title text |
### AlertDescription
Detailed description text.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Description text |
---
## Usage Examples
### Basic Alert
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_alert::*;
#[component]
pub fn MyComponent() -> impl IntoView {
view! {
<Alert variant=AlertVariant::Default>
<AlertTitle>"Heads up!"</AlertTitle>
<AlertDescription>
"You can add components to your app using the cli."
</AlertDescription>
</Alert>
}
}
```
### Alert Variants
```rust
view! {
<div class="space-y-4">
<Alert variant=AlertVariant::Default>
<AlertDescription>"Default alert"</AlertDescription>
</Alert>
<Alert variant=AlertVariant::Info>
<AlertDescription>"Information message"</AlertDescription>
</Alert>
<Alert variant=AlertVariant::Success>
<AlertDescription>"Success! Operation completed."</AlertDescription>
</Alert>
<Alert variant=AlertVariant::Warning>
<AlertDescription>"Warning! Please review."</AlertDescription>
</Alert>
<Alert variant=AlertVariant::Destructive>
<AlertDescription>"Error! Something went wrong."</AlertDescription>
</Alert>
</div>
}
```
---
## CSS Classes
```css
.alert {
relative w-full rounded-lg border px-4 py-3 text-sm
}
.alert-default {
border-border bg-background text-foreground
}
.alert-destructive {
border-destructive/50 text-destructive
bg-destructive/10
}
.alert-warning {
border-warning/50 text-warning
bg-warning/10
}
.alert-success {
border-success/50 text-success
bg-success/10
}
.alert-info {
border-info/50 text-info
bg-info/10
}
.alert-title {
mb-1 font-medium leading-none tracking-tight
}
.alert-description {
text-sm opacity-90
}
```
---
## Accessibility
### ARIA Attributes
- `role="alert"` - Alert role for screen readers
- Semantic heading for title
- Descriptive text for context
---
## TypeScript API
```typescript
interface AlertProps {
variant?: 'default' | 'destructive' | 'warning' | 'info' | 'success';
className?: string;
children?: React.ReactNode;
}
export const Alert: React.FC<AlertProps>;
export const AlertTitle: React.FC<ComponentProps>;
export const AlertDescription: React.FC<ComponentProps>;
```
---
*Source: [packages/leptos/alert/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/alert/src/default.rs)*

View File

@@ -0,0 +1,103 @@
# Aspect Ratio Component API
A container that maintains a consistent aspect ratio for its content.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-aspect-ratio = "0.7"
```
```rust
use shadcn_ui_leptos_aspect_ratio::AspectRatio;
```
---
## Component API
### AspectRatio
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `ratio` | `f64` | **Required** | Aspect ratio (width/height) |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
---
## Usage Examples
### Basic Aspect Ratio
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_aspect_ratio::AspectRatio;
#[component]
pub fn MyComponent() -> impl IntoView {
view! {
<AspectRatio ratio=16.0 / 9.0>
<img src="/image.jpg" alt="16:9 image" />
</AspectRatio>
}
}
```
### Square Container
```rust
view! {
<AspectRatio ratio=1.0>
<div class="bg-muted">"Square content"</div>
</AspectRatio>
}
```
---
## CSS Classes
```css
.aspect-ratio {
relative w-full
}
.aspect-ratio::before {
content: ""
display: block
padding-bottom: calc(var(--ratio) * 100%)
}
```
---
## Common Ratios
| Ratio | Value | Usage |
|-------|-------|-------|
| Square | 1:1 | `1.0` |
| Standard | 4:3 | `1.33` |
| Widescreen | 16:9 | `1.78` |
| Cinematic | 21:9 | `2.33` |
---
## TypeScript API
```typescript
interface AspectRatioProps {
ratio: number;
className?: string;
children?: React.ReactNode;
}
export const AspectRatio: React.FC<AspectRatioProps>;
```
---
*Source: [packages/leptos/aspect-ratio/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/aspect-ratio/src/default.rs)*

View File

@@ -0,0 +1,150 @@
# Avatar Component API
A user profile image component with fallback support.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-avatar = "0.7"
```
```rust
use shadcn_ui_leptos_avatar::Avatar;
```
---
## Import
```rust
use shadcn_ui_leptos_avatar::{
Avatar,
AvatarImage,
AvatarFallback
};
```
---
## Component API
### Avatar
Root container for avatar components.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
### AvatarImage
The image to display.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `src` | `MaybeProp<String>` | **Required** | Image URL |
| `alt` | `MaybeProp<String>` | `None` | Alt text |
### AvatarFallback
Fallback content when image fails to load.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Fallback content |
---
## Usage Examples
### Basic Avatar
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_avatar::*;
#[component]
pub fn MyComponent() -> impl IntoView {
view! {
<Avatar>
<AvatarImage src="https://github.com/user.png" alt="User" />
<AvatarFallback>"JD"</AvatarFallback>
</Avatar>
}
}
```
### Avatar with Initials
```rust
view! {
<Avatar>
<AvatarImage src=MaybeProp::Derived(None.into()) />
<AvatarFallback class="bg-primary text-primary-foreground">
"AB"
</AvatarFallback>
</Avatar>
}
```
---
## CSS Classes
```css
.avatar {
relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full
}
.avatar-image {
aspect-square h-full w-full
}
.avatar-fallback {
flex h-full w-full items-center justify-center
rounded-full bg-muted
}
```
---
## Accessibility
### ARIA Attributes
- `alt` - Image description
- Semantic fallback text
---
## TypeScript API
```typescript
interface AvatarProps {
className?: string;
children?: React.ReactNode;
}
interface AvatarImageProps {
src: string;
alt?: string;
}
interface AvatarFallbackProps {
className?: string;
children: React.ReactNode;
}
export const Avatar: React.FC<AvatarProps>;
export const AvatarImage: React.FC<AvatarImageProps>;
export const AvatarFallback: React.FC<AvatarFallbackProps>;
```
---
*Source: [packages/leptos/avatar/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/avatar/src/default.rs)*

View File

@@ -0,0 +1,165 @@
# Badge Component API
A small status indicator component for displaying labels and counts.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-badge = "0.7"
```
```rust
use shadcn_ui_leptos_badge::Badge;
```
---
## Import
```rust
use shadcn_ui_leptos_badge::{
Badge,
BadgeVariant
};
```
---
## Component API
### Badge
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `variant` | `MaybeProp<BadgeVariant>` | `Default` | Badge style |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Badge content |
### BadgeVariant
```rust
pub enum BadgeVariant {
Default, // Neutral gray
Primary, // Brand primary color
Secondary, // Secondary color
Destructive, // Red for errors
Outline, // Bordered outline
Success, // Green for success
}
```
---
## Usage Examples
### Basic Badge
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_badge::*;
#[component]
pub fn MyComponent() -> impl IntoView {
view! {
<Badge variant=BadgeVariant::Default>
"New"
</Badge>
}
}
```
### Badge Variants
```rust
view! {
<div class="flex gap-2">
<Badge variant=BadgeVariant::Default>"Default"</Badge>
<Badge variant=BadgeVariant::Primary>"Primary"</Badge>
<Badge variant=BadgeVariant::Secondary>"Secondary"</Badge>
<Badge variant=BadgeVariant::Destructive>"Error"</Badge>
<Badge variant=BadgeVariant::Outline>"Outline"</Badge>
<Badge variant=BadgeVariant::Success>"Success"</Badge>
</div>
}
```
### Count Badge
```rust
view! {
<div class="relative">
<button>"Notifications"</button>
<Badge class="absolute -top-2 -right-2 px-2 py-0.5">
"3"
</Badge>
</div>
}
```
---
## CSS Classes
```css
.badge {
inline-flex items-center rounded-full border
px-2.5 py-0.5 text-xs font-semibold
transition-colors focus:outline-none focus:ring-2
focus:ring-ring focus:ring-offset-2
}
.badge-default {
border-transparent bg-primary text-primary-foreground
hover:bg-primary/80
}
.badge-secondary {
border-transparent bg-secondary
text-secondary-foreground hover:bg-secondary/80
}
.badge-destructive {
border-transparent bg-destructive
text-destructive-foreground hover:bg-destructive/80
}
.badge-outline {
text-foreground
}
.badge-success {
border-transparent bg-green-500 text-white
hover:bg-green-600
}
```
---
## Accessibility
### ARIA Attributes
- `aria-label` - For status badges
- Semantic color usage for meaning
---
## TypeScript API
```typescript
interface BadgeProps {
variant?: 'default' | 'primary' | 'secondary' | 'destructive' | 'outline' | 'success';
className?: string;
children?: React.ReactNode;
}
export const Badge: React.FC<BadgeProps>;
```
---
*Source: [packages/leptos/badge/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/badge/src/default.rs)*

View File

@@ -0,0 +1,175 @@
# Breadcrumb Component API
A navigation component showing the user's location in a hierarchy.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-breadcrumb = "0.7"
```
```rust
use shadcn_ui_leptos_breadcrumb::Breadcrumb;
```
---
## Import
```rust
use shadcn_ui_leptos_breadcrumb::{
Breadcrumb,
BreadcrumbList,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbPage,
BreadcrumbSeparator,
BreadcrumbEllipsis
};
```
---
## Component API
### Breadcrumb
Root container for breadcrumb navigation.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
### BreadcrumbList
Unordered list container.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
### BreadcrumbItem
Individual breadcrumb item.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
### BreadcrumbLink
Clickable breadcrumb link.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `href` | `MaybeProp<String>` | **Required** | Link URL |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
### BreadcrumbPage
Current page (non-link).
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
### BreadcrumbSeparator
Visual separator between items.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
---
## Usage Examples
### Basic Breadcrumb
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_breadcrumb::*;
#[component]
pub fn MyComponent() -> impl IntoView {
view! {
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">"Home"</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href="/components">"Components"</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>"Breadcrumb"</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
}
}
```
---
## CSS Classes
```css
.breadcrumb-list {
flex items-center flex-wrap text-sm
}
.breadcrumb-item {
inline-flex items-center gap-1.5
}
.breadcrumb-link {
transition-colors hover:text-foreground
}
.breadcrumb-page {
font-normal text-foreground
}
.breadcrumb-separator {
opacity-50
}
```
---
## Accessibility
### ARIA Attributes
- `aria-label="breadcrumb"` - Breadcrumb navigation label
- `aria-current="page"` - Current page indicator
---
## TypeScript API
```typescript
interface BreadcrumbProps {
className?: string;
children?: React.ReactNode;
}
export const Breadcrumb: React.FC<BreadcrumbProps>;
export const BreadcrumbList: React.FC<ComponentProps>;
export const BreadcrumbItem: React.FC<ComponentProps>;
export const BreadcrumbLink: React.FC<{ href: string }>;
export const BreadcrumbPage: React.FC<ComponentProps>;
export const BreadcrumbSeparator: React.FC<ComponentProps>;
```
---
*Source: [packages/leptos/breadcrumb/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/breadcrumb/src/default.rs)*

View File

@@ -0,0 +1,383 @@
# Button Component API
A versatile button component with multiple variants, sizes, and states for all interactive needs.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-button = "0.7"
```
```rust
use shadcn_ui_leptos_button::Button;
```
---
## Import
```rust
// Default theme
use shadcn_ui_leptos_button::{
Button,
ButtonVariant,
ButtonSize,
ButtonChildProps
};
// New York theme
use shadcn_ui_leptos_button::{
ButtonNewYork,
ButtonVariantNewYork,
ButtonSizeNewYork
};
// Signal-managed variant
use shadcn_ui_leptos_button::{
SignalManagedButton,
SignalManagedButtonState
};
```
---
## Component API
### Button
#### Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `variant` | `MaybeProp<ButtonVariant>` | `Default` | Visual style variant |
| `size` | `MaybeProp<ButtonSize>` | `Default` | Button size |
| `on_click` | `Option<Callback<()>>` | `None` | Click event handler |
| `disabled` | `Signal<bool>` | `false` | Disable button interaction |
| `loading` | `Signal<bool>` | `false` | Show loading spinner |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `id` | `MaybeProp<String>` | `None` | Unique identifier |
| `style` | `Signal<Style>` | `None` | Inline styles |
| `aria_label` | `MaybeProp<String>` | `None` | Accessible name |
| `aria_describedby` | `MaybeProp<String>` | `None` | Description reference |
| `as_child` | `Option<Callback<ButtonChildProps, AnyView>>` | `None` | Render as custom element |
| `children` | `Option<Children>` | `None` | Button content |
#### ButtonVariant
```rust
pub enum ButtonVariant {
Default, // Primary brand color
Destructive, // Red, destructive actions
Outline, // Bordered outline
Secondary, // Secondary color
Ghost, // No background, hover effect
Link, // Text link style
}
```
#### ButtonSize
```rust
pub enum ButtonSize {
Default, // Standard size (h-10 px-4 py-2)
Sm, // Small (h-9 rounded-md px-3)
Lg, // Large (h-11 rounded-md px-8)
Icon, // Square icon (h-10 w-10)
}
```
#### ButtonChildProps
When using `as_child`, these props are passed to your custom component:
```rust
pub struct ButtonChildProps {
pub class: String, // CSS classes
pub id: String, // Element ID
pub style: String, // Inline styles
pub disabled: bool, // Disabled state
pub r#type: String, // HTML type (button)
pub onclick: Option<Callback<()>>, // Click handler
}
```
---
## Usage Examples
### Basic Button
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_button::Button;
#[component]
pub fn MyApp() -> impl IntoView {
view! {
<Button on_click=move || println!("Clicked!")>
"Click me"
</Button>
}
}
```
### Variants
```rust
view! {
<div class="flex gap-2">
<Button variant=ButtonVariant::Default>"Default"</Button>
<Button variant=ButtonVariant::Destructive>"Destructive"</Button>
<Button variant=ButtonVariant::Outline>"Outline"</Button>
<Button variant=ButtonVariant::Secondary>"Secondary"</Button>
<Button variant=ButtonVariant::Ghost>"Ghost"</Button>
<Button variant=ButtonVariant::Link>"Link"</Button>
</div>
}
```
### Sizes
```rust
view! {
<div class="flex items-center gap-2">
<Button size=ButtonSize::Sm>"Small"</Button>
<Button size=ButtonSize::Default>"Default"</Button>
<Button size=ButtonSize::Lg>"Large"</Button>
<Button size=ButtonSize::Icon>
<span>"+"</span>
</Button>
</div>
}
```
### With Loading State
```rust
#[component]
pub fn SaveButton() -> impl IntoView {
let (loading, set_loading) = signal(false);
let handle_save = move |_| {
set_loading.set(true);
// Simulate async operation
setTimeout(move || {
set_loading.set(false);
}, 2000);
};
view! {
<Button
on_click=handle_save
loading=loading.into()
>
"Save"
</Button>
}
}
```
### Disabled State
```rust
view! {
<Button disabled=Signal::derive(|| true)>
"Disabled"
</Button>
}
```
### Custom Styling
```rust
view! {
<Button
variant=ButtonVariant::Primary
class="w-full shadow-lg"
id="submit-button"
style=Style::new("margin-top: 1rem")
>
"Submit"
</Button>
}
```
### With Icon
```rust
view! {
<Button variant=ButtonVariant::Outline size=ButtonSize::Sm>
<span class="mr-2">"+"</span>
"Add New"
</Button>
}
```
### As Child (Custom Element)
```rust
view! {
<Button
as_child=Callback::new(|props| {
view! {
<a
class=props.class
id=props.id
style=props.style
href="https://example.com"
>
"Link Button"
</a>
}.into_any()
})
/>
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Enter** | Activates button |
| **Space** | Activates button |
| **Tab** | Focuses next button |
### ARIA Attributes
The component automatically manages ARIA attributes:
- `aria-label` - Custom accessible label
- `aria-describedby` - References description element
- `aria-busy` - Set to "true" when loading
- `disabled` - HTML disabled attribute
### Screen Reader Support
```rust
// Good: Provide accessible label
<Button aria_label="Close dialog".to_string()>
<span>"X"</span>
</Button>
// Good: Use descriptive text
<Button>"Delete Account"</Button>
// Avoid: Non-descriptive icons without labels
<Button>
<span>X</span> // Screen reader won't understand
</Button>
```
---
## Signal-Managed Variant
The `SignalManagedButton` provides built-in state management:
```rust
use shadcn_ui_leptos_button::SignalManagedButton;
#[component]
pub fn MyForm() -> impl IntoView {
let state = SignalManagedButtonState::new();
view! {
<SignalManagedButton
state=state
on_click=move || println!("Clicked!")
>
"Submit"
</SignalManagedButton>
}
}
```
---
## CSS Classes
### Base Classes
```css
.shadcn-button {
inline-flex items-center justify-center
whitespace-nowrap rounded-md text-sm font-medium
ring-offset-background transition-colors
focus-visible:outline-none focus-visible:ring-2
focus-visible:ring-ring focus-visible:ring-offset-2
disabled:pointer-events-none disabled:opacity-50
}
```
### Variant Classes
| Variant | CSS Classes |
|---------|-------------|
| `Default` | `bg-primary text-primary-foreground hover:bg-primary/90` |
| `Destructive` | `bg-destructive text-destructive-foreground hover:bg-destructive/90` |
| `Outline` | `border border-input bg-background hover:bg-accent hover:text-accent-foreground` |
| `Secondary` | `bg-secondary text-secondary-foreground hover:bg-secondary/80` |
| `Ghost` | `hover:bg-accent hover:text-accent-foreground` |
| `Link` | `text-primary underline-offset-4 hover:underline` |
### Size Classes
| Size | CSS Classes |
|------|-------------|
| `Default` | `h-10 px-4 py-2` |
| `Sm` | `h-9 rounded-md px-3` |
| `Lg` | `h-11 rounded-md px-8` |
| `Icon` | `h-10 w-10` |
---
## TypeScript API
```typescript
interface ButtonProps {
variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link';
size?: 'default' | 'sm' | 'lg' | 'icon';
onClick?: () => void;
disabled?: boolean;
loading?: boolean;
className?: string;
id?: string;
style?: React.CSSProperties;
ariaLabel?: string;
ariaDescribedby?: string;
asChild?: boolean;
children?: React.ReactNode;
}
export const Button: React.FC<ButtonProps>;
```
---
## Best Practices
1. **Use clear, descriptive labels** - "Submit" is better than "OK"
2. **Match variant to action** - Use `Destructive` for irreversible actions
3. **Provide loading feedback** - Use the `loading` prop for async actions
4. **Maintain consistent sizing** - Keep buttons within a section the same size
5. **Consider touch targets** - Minimum 44x44 pixels for mobile
---
## See Also
- [Input](./input.md) - Form input component
- [Dialog](./dialog.md) - Modal dialog component
- [Accessibility Guide](../ACCESSIBILITY_GUIDE.md)
---
*Source: [packages/leptos/button/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/button/src/default.rs)*

View File

@@ -0,0 +1,107 @@
# Calendar Component API
A calendar component for date selection and display.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-calendar = "0.7"
```
```rust
use shadcn_ui_leptos_calendar::Calendar;
```
---
## Component API
### Calendar
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `Signal<Option<NaiveDate>>` | **Required** | Selected date |
| `on_change` | `Option<Callback<Option<NaiveDate>>>` | `None` | Change handler |
| `disabled` | `Signal<bool>` | `false` | Disable calendar |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
---
## Usage Examples
### Basic Calendar
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_calendar::Calendar;
use chrono::NaiveDate;
#[component]
pub fn MyComponent() -> impl IntoView {
let (date, set_date) = signal(None);
view! {
<Calendar
value=date.into()
on_change=Some(Callback::new(move |d| set_date.set(d)))
/>
}
}
```
---
## CSS Classes
```css
.calendar {
p-3 space-y-4
}
.calendar-day {
p-2 text-center hover:bg-accent rounded-md cursor-pointer
}
.calendar-day-selected {
bg-primary text-primary-foreground
}
.calendar-day-disabled {
opacity-50 cursor-not-allowed
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Arrow Keys** | Navigate dates |
| **Page Up/Down** | Navigate months |
| **Enter** | Select date |
---
## TypeScript API
```typescript
interface CalendarProps {
value?: Date | null;
onChange?: (date: Date | null) => void;
disabled?: boolean;
className?: string;
}
export const Calendar: React.FC<CalendarProps>;
```
---
*Source: [packages/leptos/calendar/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/calendar/src/default.rs)*

499
docs/components/api/card.md Normal file
View File

@@ -0,0 +1,499 @@
# Card Component API
A versatile card component for organizing and displaying content with optional header, title, description, content, and footer sections.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-card = "0.7"
```
```rust
use shadcn_ui_leptos_card::Card;
```
---
## Import
```rust
// Default theme
use shadcn_ui_leptos_card::{
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
CardFooter,
CardVariant,
InteractiveCard
};
// New York theme
use shadcn_ui_leptos_card::{
Card as CardNewYork,
CardHeader as CardHeaderNewYork,
// ... other components
};
// Signal-managed variant
use shadcn_ui_leptos_card::{
SignalManagedCard,
SignalManagedCardState
};
```
---
## Component API
### Card
The main card container component.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `id` | `MaybeProp<String>` | `None` | Unique identifier |
| `style` | `Signal<Style>` | `None` | Inline styles |
| `variant` | `MaybeProp<CardVariant>` | `Default` | Visual style variant |
| `interactive` | `Signal<bool>` | `false` | Enable hover/click effects |
| `children` | `Option<Children>` | `None` | Card content |
### CardHeader
Header section containing title and description.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `id` | `MaybeProp<String>` | `None` | Unique identifier |
| `style` | `Signal<Style>` | `None` | Inline styles |
| `children` | `Option<Children>` | `None` | Header content |
### CardTitle
Title text within the card header.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `id` | `MaybeProp<String>` | `None` | Unique identifier |
| `style` | `Signal<Style>` | `None` | Inline styles |
| `level` | `MaybeProp<u8>` | `2` | Heading level (h1-h6) |
| `children` | `Option<Children>` | `None` | Title text |
### CardDescription
Description text within the card header.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `id` | `MaybeProp<String>` | `None` | Unique identifier |
| `style` | `Signal<Style>` | `None` | Inline styles |
| `children` | `Option<Children>` | `None` | Description text |
### CardContent
Main content area of the card.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `id` | `MaybeProp<String>` | `None` | Unique identifier |
| `style` | `Signal<Style>` | `None` | Inline styles |
| `children` | `Option<Children>` | `None` | Content |
### CardFooter
Footer section for actions or metadata.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `id` | `MaybeProp<String>` | `None` | Unique identifier |
| `style` | `Signal<Style>` | `None` | Inline styles |
| `children` | `Option<Children>` | `None` | Footer content |
---
## CardVariant
```rust
pub enum CardVariant {
Default, // Standard card styling
Destructive, // Red border/background for errors
Warning, // Yellow border/background for warnings
Success, // Green border/background for success
}
```
---
## Usage Examples
### Basic Card
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_card::*;
#[component]
pub fn MyComponent() -> impl IntoView {
view! {
<Card>
<CardContent>
<p>"Basic card content"</p>
</CardContent>
</Card>
}
}
```
### Complete Card Structure
```rust
view! {
<Card>
<CardHeader>
<CardTitle>"Card Title"</CardTitle>
<CardDescription>
"A brief description of the card's content"
</CardDescription>
</CardHeader>
<CardContent>
<p>"Main content goes here."</p>
</CardContent>
<CardFooter>
<button>"Action"</button>
</CardFooter>
</Card>
}
```
### Content Only Card
```rust
view! {
<Card>
<CardContent class="p-6">
<h3 class="text-lg font-semibold">"Simple Card"</h3>
<p class="mt-2">"Just content, no header or footer."</p>
</CardContent>
</Card>
}
```
### Interactive Card
```rust
#[component]
pub fn ClickableCard() -> impl IntoView {
let (clicked, set_clicked) = signal(false);
view! {
<Card
interactive=Signal::derive(|| true)
on:click=move |_| set_clicked.update(|n| *n = !n)
class="cursor-pointer"
>
<CardHeader>
<CardTitle>"Click Me!"</CardTitle>
</CardHeader>
<CardContent>
<p>{move || if clicked.get() { "Clicked!" } else { "Not clicked" }}</p>
</CardContent>
</Card>
}
}
```
### Variant Cards
```rust
view! {
<div class="grid gap-4">
<Card variant=CardVariant::Default>
<CardHeader>
<CardTitle>"Default"</CardTitle>
</CardHeader>
</Card>
<Card variant=CardVariant::Success>
<CardHeader>
<CardTitle>"Success"</CardTitle>
<CardDescription>"Operation completed"</CardDescription>
</CardHeader>
</Card>
<Card variant=CardVariant::Warning>
<CardHeader>
<CardTitle>"Warning"</CardTitle>
<CardDescription>"Please review this"</CardDescription>
</CardHeader>
</Card>
<Card variant=CardVariant::Destructive>
<CardHeader>
<CardTitle>"Error"</CardTitle>
<CardDescription>"Something went wrong"</CardDescription>
</CardHeader>
</Card>
</div>
}
```
### Profile Card
```rust
#[component]
pub fn ProfileCard() -> impl IntoView {
view! {
<Card class="max-w-sm">
<CardHeader>
<div class="flex items-center space-x-4">
<div class="h-12 w-12 rounded-full bg-primary" />
<div>
<CardTitle class="text-lg">"John Doe"</CardTitle>
<CardDescription>"Software Engineer"</CardDescription>
</div>
</div>
</CardHeader>
<CardContent>
<p class="text-sm">
"Passionate about building great user experiences \
and writing clean, maintainable code."
</p>
</CardContent>
<CardFooter>
<div class="flex space-x-2">
<button class="text-sm">"View Profile"</button>
<button class="text-sm">"Contact"</button>
</div>
</CardFooter>
</Card>
}
}
```
### Stats Card
```rust
#[component]
pub fn StatsCard() -> impl IntoView {
view! {
<Card>
<CardHeader>
<CardDescription>"Total Revenue"</CardDescription>
<CardTitle class="text-3xl">"$45,231.89"</CardTitle>
</CardHeader>
<CardContent>
<div class="text-xs text-muted-foreground">
"+20.1% from last month"
</div>
</CardContent>
</Card>
}
}
```
### Custom Styled Card
```rust
view! {
<Card
class="bg-gradient-to-br from-purple-500 to-pink-500 text-white border-0"
>
<CardContent class="p-8">
<h2 class="text-2xl font-bold">"Featured Content"</h2>
<p class="mt-2 opacity-90">
"Cards can be completely customized with your own styles"
</p>
</CardContent>
</Card>
}
```
### Grid of Cards
```rust
view! {
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{(0..6).map(|i| {
view! {
<Card>
<CardHeader>
<CardTitle>{format!("Card {}", i + 1)}</CardTitle>
</CardHeader>
<CardContent>
<p>"Content for card"</p>
</CardContent>
</Card>
}
}).collect::<Vec<_>>()}
</div>
}
```
---
## Accessibility
### Semantic Structure
Cards use semantic HTML elements:
- `<article>` for the card container
- `<h2>` (default) for the card title
- Proper heading hierarchy
### Keyboard Navigation
For interactive cards:
| Key | Action |
|-----|--------|
| **Tab** | Focus card (when interactive) |
| **Enter** | Activate card (when interactive) |
| **Space** | Activate card (when interactive) |
### ARIA Attributes
```rust
// Good: Descriptive card title
<Card>
<CardHeader>
<CardTitle>"User Profile Settings"</CardTitle>
</CardHeader>
</Card>
// Good: Interactive cards indicate clickability
<Card
interactive=Signal::derive(|| true)
role="button"
aria_label="View details"
>
```
---
## CSS Classes
### Card Classes
```css
.shadcn-card {
rounded-lg border bg-card text-card-foreground shadow-sm
}
```
### Variant Classes
| Variant | CSS Classes |
|---------|-------------|
| `Default` | Base classes only |
| `Destructive` | `border-destructive bg-destructive/5` |
| `Warning` | `border-warning bg-warning/5` |
| `Success` | `border-success bg-success/5` |
### Interactive Classes
```css
.shadcn-card--interactive {
cursor-pointer hover:shadow-md transition-shadow
}
```
### Subcomponent Classes
| Component | Base Classes |
|-----------|-------------|
| `CardHeader` | `flex flex-col space-y-1.5 p-6` |
| `CardTitle` | `text-2xl font-semibold leading-none tracking-tight` |
| `CardDescription` | `text-sm text-muted-foreground` |
| `CardContent` | `p-6 pt-0` |
| `CardFooter` | `flex items-center p-6 pt-0` |
---
## TypeScript API
```typescript
interface CardProps {
className?: string;
id?: string;
style?: React.CSSProperties;
variant?: 'default' | 'destructive' | 'warning' | 'success';
interactive?: boolean;
children?: React.ReactNode;
}
interface CardHeaderProps {
className?: string;
id?: string;
style?: React.CSSProperties;
children?: React.ReactNode;
}
interface CardTitleProps {
className?: string;
id?: string;
style?: React.CSSProperties;
level?: 1 | 2 | 3 | 4 | 5 | 6;
children?: React.ReactNode;
}
interface CardDescriptionProps {
className?: string;
id?: string;
style?: React.CSSProperties;
children?: React.ReactNode;
}
interface CardContentProps {
className?: string;
id?: string;
style?: React.CSSProperties;
children?: React.ReactNode;
}
interface CardFooterProps {
className?: string;
id?: string;
style?: React.CSSProperties;
children?: React.ReactNode;
}
export const Card: React.FC<CardProps>;
export const CardHeader: React.FC<CardHeaderProps>;
export const CardTitle: React.FC<CardTitleProps>;
export const CardDescription: React.FC<CardDescriptionProps>;
export const CardContent: React.FC<CardContentProps>;
export const CardFooter: React.FC<CardFooterProps>;
```
---
## Best Practices
1. **Use consistent hierarchy** - Header → Content → Footer
2. **Provide clear titles** - Summarize card content
3. **Use descriptions sparingly** - Add context when needed
4. **Keep content focused** - One topic per card
5. **Consider mobile layouts** - Stack cards on small screens
---
## See Also
- [Separator](./separator.md) - Visual dividers
- [Button](./button.md) - Card action buttons
- [Badge](./badge.md) - Status indicators
---
*Source: [packages/leptos/card/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/card/src/default.rs)*

View File

@@ -0,0 +1,157 @@
# Carousel Component API
A rotating content display with navigation controls.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-carousel = "0.7"
```
```rust
use shadcn_ui_leptos_carousel::Carousel;
```
---
## Import
```rust
use shadcn_ui_leptos_carousel::{
Carousel,
CarouselContent,
CarouselItem,
CarouselPrevious,
CarouselNext,
CarouselDots
};
```
---
## Component API
### Carousel
Root container managing carousel state.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `current` | `Signal<usize>` | **Required** | Current slide index |
| `on_change` | `Option<Callback<usize>>` | `None` | Change handler |
| `auto_play` | `Signal<bool>` | `false` | Auto-rotate slides |
| `interval` | `MaybeProp<u64>` | `5000` | Auto-play interval (ms) |
---
## Usage Examples
### Basic Carousel
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_carousel::*;
#[component]
pub fn MyComponent() -> impl IntoView {
let (current, set_current) = signal(0);
view! {
<Carousel
current=current.into()
on_change=Some(Callback::new(move |i| set_current.set(i)))
>
<CarouselContent>
<CarouselItem>
<div class="flex aspect-square items-center justify-center bg-muted">
"Slide 1"
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-square items-center justify-center bg-muted">
"Slide 2"
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-square items-center justify-center bg-muted">
"Slide 3"
</div>
</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
<CarouselDots />
</Carousel>
}
}
```
---
## CSS Classes
```css
.carousel {
relative
}
.carousel-content {
flex overflow-hidden
}
.carousel-item {
min-w-0 shrink-0 grow-0 basis-full
}
.carousel-previous,
.carousel-next {
absolute h-8 w-8 rounded-full border bg-background
top-1/2 -translate-y-1/2
}
.carousel-previous {
left-4
}
.carousel-next {
right-4
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Arrow Left** | Previous slide |
| **Arrow Right** | Next slide |
---
## TypeScript API
```typescript
interface CarouselProps {
current: number;
onChange?: (index: number) => void;
autoPlay?: boolean;
interval?: number;
}
export const Carousel: React.FC<CarouselProps>;
export const CarouselContent: React.FC<ComponentProps>;
export const CarouselItem: React.FC<ComponentProps>;
export const CarouselPrevious: React.FC<ButtonProps>;
export const CarouselNext: React.FC<ButtonProps>;
```
---
*Source: [packages/leptos/carousel/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/carousel/src/default.rs)*

View File

@@ -0,0 +1,120 @@
# Checkbox Component API
A checkbox component for binary selection states.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-checkbox = "0.7"
```
```rust
use shadcn_ui_leptos_checkbox::Checkbox;
```
---
## Component API
### Checkbox
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `checked` | `Signal<bool>` | **Required** | Checkbox state |
| `on_change` | `Option<Callback<bool>>` | `None` | Change handler |
| `disabled` | `Signal<bool>` | `false` | Disable checkbox |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `id` | `MaybeProp<String>` | `None` | Unique identifier |
| `style` | `Signal<Style>` | `None` | Inline styles |
---
## Usage Examples
### Basic Checkbox
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_checkbox::Checkbox;
#[component]
pub fn MyComponent() -> impl IntoView {
let (checked, set_checked) = signal(false);
view! {
<div class="flex items-center space-x-2">
<Checkbox
checked=checked.into()
on_change=Some(Callback::new(move |is_checked| {
set_checked.set(is_checked);
}))
id="terms"
/>
<label for="terms">"Accept terms and conditions"</label>
</div>
}
}
```
### Controlled Checkbox
```rust
view! {
<Checkbox
checked=Signal::derive(|| true)
disabled=Signal::derive(|| true)
/>
}
```
---
## CSS Classes
```css
.shadcn-checkbox {
h-4 w-4 shrink-0 rounded-sm border border-primary
ring-offset-background focus-visible:outline-none
focus-visible:ring-2 focus-visible:ring-ring
focus-visible:ring-offset-2 disabled:cursor-not-allowed
disabled:opacity-50
}
.shadcn-checkbox[data-state="checked"] {
bg-primary text-primary-foreground
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Space** | Toggle checkbox |
---
## TypeScript API
```typescript
interface CheckboxProps {
checked: boolean;
onChange?: (checked: boolean) => void;
disabled?: boolean;
className?: string;
id?: string;
}
export const Checkbox: React.FC<CheckboxProps>;
```
---
*Source: [packages/leptos/checkbox/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/checkbox/src/default.rs)*

View File

@@ -0,0 +1,140 @@
# Collapsible Component API
A component that can show/hide content with animation.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-collapsible = "0.7"
```
```rust
use shadcn_ui_leptos_collapsible::Collapsible;
```
---
## Import
```rust
use shadcn_ui_leptos_collapsible::{
Collapsible,
CollapsibleTrigger,
CollapsibleContent
};
```
---
## Component API
### Collapsible
Root component managing collapsible state.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `open` | `Signal<bool>` | **Required** | Open state |
| `on_open_change` | `Option<Callback<bool>>` | `None` | Change handler |
| `disabled` | `Signal<bool>` | `false` | Disable collapsible |
### CollapsibleTrigger
Element that toggles the collapsible.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
### CollapsibleContent
Collapsible content container.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
---
## Usage Examples
### Basic Collapsible
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_collapsible::*;
#[component]
pub fn MyComponent() -> impl IntoView {
let (open, set_open) = signal(false);
view! {
<Collapsible
open=open.into()
on_open_change=Some(Callback::new(move |v| set_open.set(v)))
>
<CollapsibleTrigger>
<button>"Toggle"</button>
</CollapsibleTrigger>
<CollapsibleContent>
<div class="p-4">
"Hidden content that can be shown/hidden"
</div>
</CollapsibleContent>
</Collapsible>
}
}
```
---
## CSS Classes
```css
.collapsible-content {
overflow-hidden transition-all
}
.collapsible-content[data-state=open] {
animate-collapsible-down
}
.collapsible-content[data-state=closed] {
animate-collapsible-up
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Enter/Space** | Toggle collapsible |
---
## TypeScript API
```typescript
interface CollapsibleProps {
open: boolean;
onOpenChange?: (open: boolean) => void;
disabled?: boolean;
children?: React.ReactNode;
}
export const Collapsible: React.FC<CollapsibleProps>;
export const CollapsibleTrigger: React.FC<ComponentProps>;
export const CollapsibleContent: React.FC<ComponentProps>;
```
---
*Source: [packages/leptos/collapsible/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/collapsible/src/default.rs)*

View File

@@ -0,0 +1,135 @@
# Combobox Component API
A searchable select component with autocomplete functionality.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-combobox = "0.7"
```
```rust
use shadcn_ui_leptos_combobox::Combobox;
```
---
## Import
```rust
use shadcn_ui_leptos_combobox::{
Combobox,
ComboboxTrigger,
ComboboxContent,
ComboboxInput,
ComboboxItem,
ComboboxEmpty
};
```
---
## Component API
### Combobox
Root component managing combobox state.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `Signal<Option<String>>` | **Required** | Selected value |
| `on_change` | `Option<Callback<Option<String>>>` | `None` | Change handler |
| `options` | `Vec<String>` | **Required** | Available options |
| `filterable` | `Signal<bool>` | `true` | Enable search filtering |
---
## Usage Examples
### Basic Combobox
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_combobox::*;
#[component]
pub fn MyComponent() -> impl IntoView {
let (value, set_value) = signal(None);
let options = vec![
"Apple".to_string(),
"Banana".to_string(),
"Orange".to_string(),
];
view! {
<Combobox
value=value.into()
on_change=Some(Callback::new(move |v| set_value.set(v)))
options=options
>
<ComboboxTrigger>
<button>"Select fruit"</button>
</ComboboxTrigger>
<ComboboxContent>
<ComboboxInput placeholder="Search..." />
<ComboboxEmpty>"No results found"</ComboboxEmpty>
// Items rendered automatically
</ComboboxContent>
</Combobox>
}
}
```
---
## CSS Classes
```css
.combobox-content {
z-50 min-w-[8rem] overflow-hidden rounded-md
border bg-popover p-1 text-popover-foreground
shadow-md
}
.combobox-item {
relative flex cursor-pointer select-none items-center
rounded-sm px-2 py-1.5 text-sm outline-none
transition-colors hover:bg-accent hover:text-accent-foreground
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Type** | Filter options |
| **Arrow Keys** | Navigate options |
| **Enter** | Select option |
| **Escape** | Close dropdown |
---
## TypeScript API
```typescript
interface ComboboxProps {
value: string | null;
onChange?: (value: string | null) => void;
options: string[];
filterable?: boolean;
}
export const Combobox: React.FC<ComboboxProps>;
```
---
*Source: [packages/leptos/combobox/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/combobox/src/default.rs)*

View File

@@ -0,0 +1,161 @@
# Command Component API
A command palette component for quick actions and navigation.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-command = "0.7"
```
```rust
use shadcn_ui_leptos_command::Command;
```
---
## Import
```rust
use shadcn_ui_leptos_command::{
Command,
CommandInput,
CommandList,
CommandItem,
CommandGroup,
CommandSeparator,
CommandEmpty
};
```
---
## Component API
### Command
Root container for command palette.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `open` | `Signal<bool>` | **Required** | Open state |
| `on_open_change` | `Option<Callback<bool>>` | `None` | Change handler |
### CommandInput
Search input for filtering commands.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `placeholder` | `MaybeProp<String>` | `"Type a command..."` | Placeholder text |
### CommandItem
Individual command item.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `String` | **Required** | Search value |
| `on_select` | `Option<Callback<()>>` | `None` | Select handler |
---
## Usage Examples
### Basic Command Palette
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_command::*;
#[component]
pub fn MyComponent() -> impl IntoView {
let (open, set_open) = signal(false);
view! {
<div>
<button on:click=move |_| set_open.set(true)>
"Open Command Palette"
</button>
<Command
open=open.into()
on_open_change=Some(Callback::new(move |v| set_open.set(v)))
>
<CommandInput placeholder="Type a command..." />
<CommandList>
<CommandEmpty>"No results found"</CommandEmpty>
<CommandGroup heading="Suggestions">
<CommandItem value="calendar" on_select=Some(Callback::new(move |_| println!("Calendar")))>
"Calendar"
</CommandItem>
<CommandItem value="settings">
"Settings"
</CommandItem>
</CommandGroup>
</CommandList>
</Command>
</div>
}
}
```
---
## CSS Classes
```css
.command {
flex h-full w-full flex-col overflow-hidden rounded-md
bg-popover text-popover-foreground
}
.command-input {
flex h-11 w-full rounded-md bg-transparent py-3
text-sm outline-none placeholder:text-muted-foreground
}
.command-item {
relative flex cursor-pointer select-none items-center
rounded-sm px-2 py-1.5 text-sm outline-none
hover:bg-accent hover:text-accent-foreground
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Type** | Filter commands |
| **Arrow Keys** | Navigate items |
| **Enter** | Execute command |
| **Escape** | Close palette |
| **Ctrl+K** | Open palette (global) |
---
## TypeScript API
```typescript
interface CommandProps {
open: boolean;
onOpenChange?: (open: boolean) => void;
}
export const Command: React.FC<CommandProps>;
export const CommandInput: React.FC<{ placeholder?: string }>;
export const CommandList: React.FC<ComponentProps>;
export const CommandItem: React.FC<{ value: string; onSelect?: () => void }>;
```
---
*Source: [packages/leptos/command/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/command/src/default.rs)*

View File

@@ -0,0 +1,149 @@
# Context Menu Component API
A right-click context menu for performing actions on elements.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-context-menu = "0.7"
```
```rust
use shadcn_ui_leptos_context_menu::ContextMenu;
```
---
## Import
```rust
use shadcn_ui_leptos_context_menu::{
ContextMenu,
ContextMenuTrigger,
ContextMenuContent,
ContextMenuItem,
ContextMenuLabel,
ContextMenuSeparator
};
```
---
## Component API
### ContextMenu
Root component managing menu state.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `open` | `Signal<bool>` | **Required** | Open state |
| `on_open_change` | `Option<Callback<bool>>` | `None` | Change handler |
### ContextMenuTrigger
Element that triggers the context menu on right-click.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
### ContextMenuItem
Individual menu item.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `on_click` | `Option<Callback<()>>` | `None` | Click handler |
---
## Usage Examples
### Basic Context Menu
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_context_menu::*;
#[component]
pub fn MyComponent() -> impl IntoView {
let (open, set_open) = signal(false);
view! {
<ContextMenu
open=open.into()
on_open_change=Some(Callback::new(move |v| set_open.set(v)))
>
<ContextMenuTrigger>
<div class="p-4 border">"Right-click me"</div>
</ContextMenuTrigger>
<ContextMenuContent>
<ContextMenuItem on_click=Some(Callback::new(move |_| println!("Copy")))>
"Copy"
</ContextMenuItem>
<ContextMenuItem on_click=Some(Callback::new(move |_| println!("Paste")))>
"Paste"
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem>"Delete"</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
}
}
```
---
## CSS Classes
```css
.context-menu-content {
z-50 min-w-[8rem] overflow-hidden rounded-md
border bg-popover p-1 text-popover-foreground
shadow-md
}
.context-menu-item {
relative flex cursor-pointer select-none items-center
rounded-sm px-2 py-1.5 text-sm outline-none
transition-colors hover:bg-accent hover:text-accent-foreground
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Arrow Keys** | Navigate items |
| **Enter** | Select item |
| **Escape** | Close menu |
---
## TypeScript API
```typescript
interface ContextMenuProps {
open: boolean;
onOpenChange?: (open: boolean) => void;
children?: React.ReactNode;
}
export const ContextMenu: React.FC<ContextMenuProps>;
export const ContextMenuTrigger: React.FC<ComponentProps>;
export const ContextMenuContent: React.FC<ComponentProps>;
export const ContextMenuItem: React.FC<ComponentProps>;
```
---
*Source: [packages/leptos/context-menu/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/context-menu/src/default.rs)*

View File

@@ -0,0 +1,488 @@
# Dialog Component API
A modal dialog component for displaying important information or capturing user input in an overlay.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-dialog = "0.7"
```
```rust
use shadcn_ui_leptos_dialog::Dialog;
```
---
## Import
```rust
// Default theme
use shadcn_ui_leptos_dialog::{
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription,
DialogFooter,
DialogClose
};
// New York theme
use shadcn_ui_leptos_dialog::{
Dialog as DialogNewYork,
DialogTrigger as DialogTriggerNewYork,
// ... other components
};
// Signal-managed variant
use shadcn_ui_leptos_dialog::{
SignalManagedDialog,
SignalManagedDialogState
};
```
---
## Component API
### Dialog (Root)
The context provider that manages dialog state.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `open` | `Signal<bool>` | **Required** | Controls dialog visibility |
| `on_open_change` | `Option<Callback<bool>>` | `None` | Called when open state changes |
| `children` | `Option<Children>` | `None` | Dialog content |
### DialogTrigger
Button that opens the dialog.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `id` | `MaybeProp<String>` | `None` | Unique identifier |
| `style` | `Signal<Style>` | `None` | Inline styles |
| `node_ref` | `AnyNodeRef` | `None` | Node reference |
| `as_child` | `Option<Callback<DialogTriggerChildProps, AnyView>>` | `None` | Render as custom element |
| `children` | `Option<Children>` | `None` | Trigger content |
### DialogContent
The main dialog container with backdrop.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `style` | `Signal<Style>` | `None` | Inline styles |
| `children` | `Option<Children>` | `None` | Dialog content |
### DialogHeader
Header section for title and description.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Header content |
### DialogTitle
Dialog title (accessibility required).
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Title text |
### DialogDescription
Optional description text.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Description text |
### DialogFooter
Footer section for action buttons.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Footer content |
### DialogClose
Button that closes the dialog.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Button content |
---
## Usage Examples
### Basic Dialog
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_dialog::*;
#[component]
pub fn MyComponent() -> impl IntoView {
let (open, set_open) = signal(false);
view! {
<Dialog open=open.into() on_open_change=Some(Callback::new(move |is_open| {
set_open.set(is_open);
}))>
<DialogTrigger>
<button>"Open Dialog"</button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>"Are you sure?"</DialogTitle>
</DialogHeader>
<div class="py-4">
"This action cannot be undone."
</div>
<DialogFooter>
<DialogClose>
<button>"Cancel"</button>
</DialogClose>
<button class="bg-destructive">"Confirm"</button>
</DialogFooter>
</DialogContent>
</Dialog>
}
}
```
### Custom Trigger Button
```rust
view! {
<Dialog open=open.into()>
<DialogTrigger as_child=Callback::new(|props| {
view! {
<button
class=props.class
on:click=move |_| set_open.set(true)
>
"Open"
</button>
}.into_any()
})>
</DialogTrigger>
// ... rest of dialog
</Dialog>
}
```
### With Description
```rust
view! {
<DialogContent>
<DialogHeader>
<DialogTitle>"Delete Account"</DialogTitle>
<DialogDescription>
"This will permanently delete your account and all associated data. \
This action cannot be undone."
</DialogDescription>
</DialogHeader>
// ... actions
</DialogContent>
}
```
### Form Dialog
```rust
#[component]
pub fn CreateUserDialog() -> impl IntoView {
let (open, set_open) = signal(false);
let (name, set_name) = signal(String::new());
let (email, set_email) = signal(String::new());
let handle_submit = move |_| {
// Create user...
set_open.set(false);
};
view! {
<Dialog open=open.into()>
<DialogTrigger>
<button>"Add User"</button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>"Create New User"</DialogTitle>
<DialogDescription>
"Enter the user's information below"
</DialogDescription>
</DialogHeader>
<form on:submit=handle_submit class="space-y-4">
<div>
<label>"Name"</label>
<input
type="text"
on:input=move |e| set_name.set(event_target_value(&e))
/>
</div>
<div>
<label>"Email"</label>
<input
type="email"
on:input=move |e| set_email.set(event_target_value(&e))
/>
</div>
<DialogFooter>
<DialogClose>
<button type="button">"Cancel"</button>
</DialogClose>
<button type="submit">"Create"</button>
</DialogFooter>
</form>
</DialogContent>
</Dialog>
}
}
```
### Confirmation Dialog
```rust
#[component]
pub fn ConfirmDelete() -> impl IntoView {
let (open, set_open) = signal(false);
view! {
<Dialog open=open.into()>
<DialogTrigger>
<button class="text-destructive">"Delete"</button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>"Delete Item"</DialogTitle>
<DialogDescription>
"Are you sure you want to delete this item? \
This action cannot be undone."
</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose>
<button variant="outline">"Cancel"</button>
</DialogClose>
<button
class="bg-destructive"
on:click=move |_| {
// Delete logic...
set_open.set(false);
}
>
"Delete"
</button>
</DialogFooter>
</DialogContent>
</Dialog>
}
}
```
### Custom Styling
```rust
view! {
<DialogContent class="sm:max-w-md">
<DialogHeader>
<DialogTitle class="text-lg font-semibold">
"Custom Styled Dialog"
</DialogTitle>
</DialogHeader>
<div class="mt-4">
"Content with custom styling"
</div>
</DialogContent>
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Escape** | Close dialog |
| **Tab** | Navigate focus within dialog |
| **Shift+Tab** | Navigate backwards |
### ARIA Attributes
The component automatically manages:
- `role="dialog"` - Dialog role
- `aria-modal="true"` - Modal state
- `aria-labelledby` - References title element
- `aria-describedby` - References description element
### Focus Management
1. **Focus trap** - Tab cycles within dialog
2. **Initial focus** - First focusable element
3. **Return focus** - Focus returns to trigger on close
4. **Backdrop click** - Click outside closes dialog
### Screen Reader Support
```rust
// Good: Proper title and description
<DialogContent>
<DialogHeader>
<DialogTitle>"Delete Account"</DialogTitle>
<DialogDescription>
"This will permanently delete your account"
</DialogDescription>
</DialogHeader>
</DialogContent>
// Good: Descriptive trigger
<DialogTrigger>
<button>"Delete Account"</button>
</DialogTrigger>
```
---
## CSS Classes
### Content Classes
```css
.dialog-content {
fixed inset-0 z-50 flex items-center justify-center
bg-background/80 backdrop-blur-sm
data-[state=open]:animate-in data-[state=closed]:animate-out
data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0
data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95
data-[state=closed]:slide-out-to-left-1/2
data-[state=closed]:slide-out-to-top-[48%]
data-[state=open]:slide-in-from-left-1/2
data-[state=open]:slide-in-from-top-[48%]
sm:rounded-lg
}
```
### Header Classes
```css
.dialog-header {
flex flex-col space-y-1.5 text-center sm:text-left
}
```
### Title Classes
```css
.dialog-title {
text-lg font-semibold leading-none tracking-tight
}
```
### Description Classes
```css
.dialog-description {
text-sm text-muted-foreground
}
```
### Footer Classes
```css
.dialog-footer {
flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2
}
```
---
## TypeScript API
```typescript
interface DialogProps {
open: boolean;
onOpenChange?: (open: boolean) => void;
children?: React.ReactNode;
}
interface DialogContentProps {
className?: string;
children?: React.ReactNode;
}
interface DialogHeaderProps {
className?: string;
children?: React.ReactNode;
}
interface DialogTitleProps {
className?: string;
children?: React.ReactNode;
}
interface DialogDescriptionProps {
className?: string;
children?: React.ReactNode;
}
interface DialogFooterProps {
className?: string;
children?: React.ReactNode;
}
export const Dialog: React.FC<DialogProps>;
export const DialogTrigger: React.FC<ButtonProps>;
export const DialogContent: React.FC<DialogContentProps>;
export const DialogHeader: React.FC<DialogHeaderProps>;
export const DialogTitle: React.FC<DialogTitleProps>;
export const DialogDescription: React.FC<DialogDescriptionProps>;
export const DialogFooter: React.FC<DialogFooterProps>;
export const DialogClose: React.FC<ButtonProps>;
```
---
## Best Practices
1. **Always provide a title** - Required for accessibility
2. **Use descriptions for context** - Explain the dialog's purpose
3. **Provide clear actions** - Make cancel/confirm obvious
4. **Handle escape key** - Built-in, but test your implementation
5. **Return focus properly** - Ensures good UX for keyboard users
---
## See Also
- [Alert Dialog](./alert-dialog.md) - For critical confirmations
- [Sheet](./sheet.md) - Side panel alternative
- [Popover](./popover.md) - Non-modal overlay
- [Accessibility Guide](../ACCESSIBILITY_GUIDE.md)
---
*Source: [packages/leptos/dialog/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/dialog/src/default.rs)*

View File

@@ -0,0 +1,139 @@
# Drawer Component API
A slide-out panel from any edge of the screen, similar to Sheet but with different styling.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-drawer = "0.7"
```
```rust
use shadcn_ui_leptos_drawer::Drawer;
```
---
## Import
```rust
use shadcn_ui_leptos_drawer::{
Drawer,
DrawerTrigger,
DrawerContent,
DrawerHeader,
DrawerTitle,
DrawerDescription,
DrawerFooter,
DrawerClose
};
```
---
## Component API
### Drawer
Root component managing drawer state.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `open` | `Signal<bool>` | **Required** | Open state |
| `on_open_change` | `Option<Callback<bool>>` | `None` | Change handler |
| `direction` | `MaybeProp<Direction>` | `Right` | Slide direction |
### Direction
```rust
pub enum Direction {
Top,
Right,
Bottom,
Left,
}
```
---
## Usage Examples
### Basic Drawer
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_drawer::*;
#[component]
pub fn MyComponent() -> impl IntoView {
let (open, set_open) = signal(false);
view! {
<Drawer
open=open.into()
on_open_change=Some(Callback::new(move |v| set_open.set(v)))
>
<DrawerTrigger>
<button>"Open Drawer"</button>
</DrawerTrigger>
<DrawerContent>
<DrawerHeader>
<DrawerTitle>"Drawer Title"</DrawerTitle>
</DrawerHeader>
<div class="p-4">
"Drawer content"
</div>
</DrawerContent>
</Drawer>
}
}
```
---
## CSS Classes
```css
.drawer-content {
fixed z-50 gap-4 bg-background p-6 shadow-lg
transition ease-in-out
}
.drawer-content[data-direction=right] {
inset-y-0 right-0 h-full w-3/4 border-l
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Escape** | Close drawer |
---
## TypeScript API
```typescript
interface DrawerProps {
open: boolean;
onOpenChange?: (open: boolean) => void;
direction?: 'top' | 'right' | 'bottom' | 'left';
}
export const Drawer: React.FC<DrawerProps>;
export const DrawerTrigger: React.FC<ComponentProps>;
export const DrawerContent: React.FC<ComponentProps>;
```
---
*Source: [packages/leptos/drawer/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/drawer/src/default.rs)*

View File

@@ -0,0 +1,144 @@
# Dropdown Menu Component API
A context menu triggered by a button or other element.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-dropdown-menu = "0.7"
```
```rust
use shadcn_ui_leptos_dropdown_menu::DropdownMenu;
```
---
## Import
```rust
use shadcn_ui_leptos_dropdown_menu::{
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuShortcut
};
```
---
## Component API
### DropdownMenu
Root component managing menu state.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `open` | `Signal<bool>` | **Required** | Open state |
| `on_open_change` | `Option<Callback<bool>>` | `None` | Change handler |
### DropdownMenuItem
Individual menu item.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `disabled` | `Signal<bool>` | `false` | Disable item |
| `on_click` | `Option<Callback<()>>` | `None` | Click handler |
---
## Usage Examples
### Basic Dropdown Menu
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_dropdown_menu::*;
#[component]
pub fn MyComponent() -> impl IntoView {
let (open, set_open) = signal(false);
view! {
<DropdownMenu
open=open.into()
on_open_change=Some(Callback::new(move |v| set_open.set(v)))
>
<DropdownMenuTrigger>
<button>"Open menu"</button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem on_click=Some(Callback::new(move |_| println!("Profile")))>
"Profile"
</DropdownMenuItem>
<DropdownMenuItem on_click=Some(Callback::new(move |_| println!("Settings")))>
"Settings"
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>"Logout"</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
}
}
```
---
## CSS Classes
```css
.dropdown-menu-content {
z-50 min-w-[8rem] overflow-hidden rounded-md
border bg-popover p-1 text-popover-foreground
shadow-md animate-in fade-in-0
}
.dropdown-menu-item {
relative flex cursor-pointer select-none items-center
rounded-sm px-2 py-1.5 text-sm outline-none
transition-colors hover:bg-accent hover:text-accent-foreground
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Arrow Down** | Next item |
| **Arrow Up** | Previous item |
| **Enter** | Select item |
| **Escape** | Close menu |
---
## TypeScript API
```typescript
interface DropdownMenuProps {
open: boolean;
onOpenChange?: (open: boolean) => void;
children?: React.ReactNode;
}
export const DropdownMenu: React.FC<DropdownMenuProps>;
export const DropdownMenuTrigger: React.FC<ComponentProps>;
export const DropdownMenuContent: React.FC<ComponentProps>;
export const DropdownMenuItem: React.FC<ComponentProps>;
```
---
*Source: [packages/leptos/dropdown-menu/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/dropdown-menu/src/default.rs)*

View File

@@ -0,0 +1,84 @@
# Error Boundary Component API
A component that catches JavaScript errors in its child component tree.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-error-boundary = "0.7"
```
```rust
use shadcn_ui_leptos_error_boundary::ErrorBoundary;
```
---
## Component API
### ErrorBoundary
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `fallback` | `Option<Callback<Error, View>>` | **Required** | Error fallback UI |
| `children` | `Option<Children>` | `None` | Child components |
---
## Usage Examples
### Basic Error Boundary
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_error_boundary::ErrorBoundary;
#[component]
pub fn MyComponent() -> impl IntoView {
view! {
<ErrorBoundary
fallback=Callback::new(|_error| {
view! {
<div class="p-4 bg-destructive/10 rounded-md">
<h2 class="text-lg font-semibold">"Something went wrong"</h2>
<p class="text-sm">"Please refresh the page"</p>
</div>
}
})
>
<p>"Child content that might error"</p>
</ErrorBoundary>
}
}
```
---
## CSS Classes
```css
.error-boundary {
p-4 border border-destructive rounded-md
}
```
---
## TypeScript API
```typescript
interface ErrorBoundaryProps {
fallback: (error: Error) => React.ReactNode;
children?: React.ReactNode;
}
export const ErrorBoundary: React.FC<ErrorBoundaryProps>;
```
---
*Source: [packages/leptos/error-boundary/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/error-boundary/src/default.rs)*

View File

@@ -0,0 +1,95 @@
# Form Component API
A form container with built-in validation and state management.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-form = "0.7"
```
```rust
use shadcn_ui_leptos_form::Form;
```
---
## Component API
### Form
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `on_submit` | `Option<Callback<FormEvent>>` | `None` | Submit handler |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
---
## Usage Examples
### Basic Form
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_form::Form;
use shadcn_ui_leptos_input::Input;
use shadcn_ui_leptos_button::Button;
#[component]
pub fn MyForm() -> impl IntoView {
let handle_submit = move |e: FormEvent| {
e.prevent_default();
// Handle form submission
};
view! {
<Form on_submit=Some(handle_submit)>
<div class="space-y-4">
<Input name="email" input_type="email" placeholder="Email" />
<Input name="password" input_type="password" placeholder="Password" />
<Button variant=ButtonVariant::Primary>"Submit"</Button>
</div>
</Form>
}
}
```
---
## CSS Classes
```css
.form {
space-y-6
}
```
---
## Accessibility
- Native HTML form validation
- Proper label association
- Error announcements
---
## TypeScript API
```typescript
interface FormProps {
onSubmit?: (event: FormEvent) => void;
className?: string;
children?: React.ReactNode;
}
export const Form: React.FC<FormProps>;
```
---
*Source: [packages/leptos/form/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/form/src/default.rs)*

View File

@@ -0,0 +1,122 @@
# Hover Card Component API
A card that appears when hovering over a trigger element.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-hover-card = "0.7"
```
```rust
use shadcn_ui_leptos_hover_card::HoverCard;
```
---
## Import
```rust
use shadcn_ui_leptos_hover_card::{
HoverCard,
HoverCardTrigger,
HoverCardContent
};
```
---
## Component API
### HoverCard
Root component managing hover state.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `open` | `Signal<bool>` | **Required** | Open state |
| `on_open_change` | `Option<Callback<bool>>` | `None` | Change handler |
### HoverCardContent
The floating card content.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
---
## Usage Examples
### Basic Hover Card
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_hover_card::*;
#[component]
pub fn MyComponent() -> impl IntoView {
let (open, set_open) = signal(false);
view! {
<HoverCard
open=open.into()
on_open_change=Some(Callback::new(move |v| set_open.set(v)))
>
<HoverCardTrigger>
<a href="#">"@username"</a>
</HoverCardTrigger>
<HoverCardContent>
<div class="space-y-2">
<h4 class="text-sm font-semibold">"User Name"</h4>
<p class="text-sm">"Bio and additional info"</p>
</div>
</HoverCardContent>
</HoverCard>
}
}
```
---
## CSS Classes
```css
.hover-card-content {
z-50 w-64 rounded-md border bg-popover p-4
text-popover-foreground shadow-md outline-none
data-[state=open]:animate-in data-[state=closed]:animate-out
}
```
---
## Accessibility
- `role="tooltip"` - Tooltip role
- Hover delay to prevent accidental triggers
---
## TypeScript API
```typescript
interface HoverCardProps {
open: boolean;
onOpenChange?: (open: boolean) => void;
children?: React.ReactNode;
}
export const HoverCard: React.FC<HoverCardProps>;
export const HoverCardTrigger: React.FC<ComponentProps>;
export const HoverCardContent: React.FC<ComponentProps>;
```
---
*Source: [packages/leptos/hover-card/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/hover-card/src/default.rs)*

View File

@@ -0,0 +1,107 @@
# Input OTP Component API
A one-time password input with individual digit fields.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-input-otp = "0.7"
```
```rust
use shadcn_ui_leptos_input_otp::InputOtp;
```
---
## Component API
### InputOtp
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `Signal<String>` | **Required** | Current OTP value |
| `on_change` | `Option<Callback<String>>` | `None` | Change handler |
| `length` | `MaybeProp<usize>` | `6` | Number of digits |
| `disabled` | `Signal<bool>` | `false` | Disable input |
---
## Usage Examples
### Basic OTP Input
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_input_otp::InputOtp;
#[component]
pub fn MyComponent() -> impl IntoView {
let (otp, set_otp) = signal(String::new());
view! {
<div class="space-y-4">
<InputOtp
value=otp.into()
on_change=Some(Callback::new(move |v| set_otp.set(v)))
length=MaybeProp::Derived(6.into())
/>
<p>{format!("Entered: {}", otp.get())}</p>
</div>
}
}
```
---
## CSS Classes
```css
.input-otp {
flex gap-2
}
.input-otp-slot {
flex h-10 w-10 items-center justify-center
rounded-md border border-input bg-background
text-center text-sm ring-offset-background
transition-all focus:outline-none focus:ring-2
focus:ring-ring focus:ring-offset-2
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Digit** | Enter digit, move to next |
| **Backspace** | Delete, move to previous |
| **Arrow Keys** | Navigate slots |
| **Paste** | Fill all slots |
---
## TypeScript API
```typescript
interface InputOtpProps {
value: string;
onChange?: (value: string) => void;
length?: number;
disabled?: boolean;
}
export const InputOtp: React.FC<InputOtpProps>;
```
---
*Source: [packages/leptos/input-otp/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/input-otp/src/default.rs)*

View File

@@ -0,0 +1,481 @@
# Input Component API
A flexible text input component with built-in validation support and accessibility features.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-input = "0.7"
```
```rust
use shadcn_ui_leptos_input::Input;
```
---
## Import
```rust
// Default theme
use shadcn_ui_leptos_input::Input;
// New York theme
use shadcn_ui_leptos_input::InputNewYork;
// Validation utilities
use shadcn_ui_leptos_input::{
ValidationRule,
ValidationError,
ValidationResult,
InputValidator,
ValidationContext,
validation_builders
};
// Signal-managed variant
use shadcn_ui_leptos_input::{
SignalManagedInput,
SignalManagedInputState
};
```
---
## Component API
### Input
#### Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `MaybeProp<String>` | `None` | Current input value |
| `on_change` | `Option<Callback<String>>` | `None` | Value change handler |
| `placeholder` | `MaybeProp<String>` | `None` | Placeholder text |
| `disabled` | `Signal<bool>` | `false` | Disable input |
| `input_type` | `MaybeProp<String>` | `"text"` | HTML input type |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `id` | `MaybeProp<String>` | `None` | Unique identifier |
| `style` | `Signal<Style>` | `None` | Inline styles |
| `validator` | `Option<InputValidator>` | `None` | Validation function |
| `validation_error` | `MaybeProp<String>` | `None` | Manual error message |
| `show_validation` | `Signal<bool>` | `false` | Show validation UI |
---
## Validation API
### ValidationRule
```rust
pub struct ValidationRule {
pub name: String,
pub validator: Box<dyn Fn(&str) -> Result<(), ValidationError>>,
}
```
### ValidationError
```rust
pub struct ValidationError {
pub code: String,
pub message: String,
}
```
### ValidationResult
```rust
pub struct ValidationResult {
pub is_valid: bool,
pub errors: Vec<ValidationError>,
}
impl ValidationResult {
pub fn new() -> Self;
pub fn is_valid(&self) -> bool;
pub fn has_errors(&self) -> bool;
}
```
### InputValidator
```rust
pub struct InputValidator {
pub rules: Vec<ValidationRule>,
}
impl InputValidator {
pub fn new() -> Self;
pub fn add_rule(mut self, rule: ValidationRule) -> Self;
pub fn validate(&self, value: &str) -> ValidationResult;
}
```
### Validation Builders
```rust
pub fn validation_builders() -> ValidationBuilders {
ValidationBuilders
}
pub struct ValidationBuilders;
impl ValidationBuilders {
pub fn required() -> ValidationRule;
pub fn min_length(min: usize) -> ValidationRule;
pub fn max_length(max: usize) -> ValidationRule;
pub fn email() -> ValidationRule;
pub fn pattern(regex: &str) -> ValidationRule;
}
```
---
## Usage Examples
### Basic Input
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_input::Input;
#[component]
pub fn MyForm() -> impl IntoView {
let (name, set_name) = signal(String::new());
view! {
<Input
value=MaybeProp::Derived(name.into())
on_change=Callback::new(move |value| {
set_name.set(value);
})
placeholder="Enter your name"
/>
}
}
```
### With Label
```rust
view! {
<div class="space-y-2">
<label for="email">"Email"</label>
<Input
id="email"
input_type="email"
placeholder="user@example.com"
/>
</div>
}
```
### Different Input Types
```rust
view! {
<div class="space-y-4">
<Input input_type="text" placeholder="Text input" />
<Input input_type="email" placeholder="Email" />
<Input input_type="password" placeholder="Password" />
<Input input_type="number" placeholder="Number" />
<Input input_type="tel" placeholder="Phone" />
<Input input_type="url" placeholder="Website" />
</div>
}
```
### With Validation
```rust
use shadcn_ui_leptos_input::validation_builders;
#[component]
pub fn EmailInput() -> impl IntoView {
let (email, set_email) = signal(String::new());
let (show_error, set_show_error) = signal(false);
let validator = validation_builders()
.required()
.email();
view! {
<div class="space-y-2">
<Input
value=MaybeProp::Derived(email.into())
on_change=Callback::new(move |value| {
set_email.set(value);
set_show_error.set(true);
})
validator=Some(validator)
show_validation=Signal::derive(|| show_error.get())
placeholder="Enter your email"
id="email"
/>
</div>
}
}
```
### Custom Validation Rules
```rust
use shadcn_ui_leptos_input::{ValidationRule, ValidationError};
let custom_validator = InputValidator::new().add_rule(
ValidationRule {
name: "custom".to_string(),
validator: Box::new(|value| {
if value.len() < 3 {
Err(ValidationError {
code: "too_short".to_string(),
message: "Must be at least 3 characters".to_string(),
})
} else {
Ok(())
}
}),
}
);
```
### Multiple Validation Rules
```rust
let password_validator = validation_builders()
.required()
.min_length(8)
.max_length(128)
.pattern(r"[A-Z]") // Must contain uppercase
.pattern(r"[0-9]"); // Must contain number
```
### Disabled State
```rust
view! {
<Input
disabled=Signal::derive(|| true)
placeholder="Disabled input"
value="Cannot change this"
/>
}
```
### Controlled Input
```rust
#[component]
pub fn SearchInput() -> impl IntoView {
let (search_query, set_search_query) = signal(String::new());
view! {
<div class="relative">
<Input
value=MaybeProp::Derived(search_query.into())
on_change=Callback::new(move |value| {
set_search_query.set(value.clone());
// Perform search...
})
placeholder="Search..."
class="pl-10"
/>
</div>
}
}
```
### Manual Error Display
```rust
#[component]
pub fn UsernameInput() -> impl IntoView {
let (username, set_username) = signal(String::new());
let (error, set_error) = signal(String::new());
let validate = move |value: String| {
if value.contains(" ") {
set_error.set("Username cannot contain spaces".to_string());
} else {
set_error.set(String::new());
}
set_username.set(value);
};
view! {
<div class="space-y-2">
<Input
value=MaybeProp::Derived(username.into())
on_change=Callback::new(validate)
validation_error=MaybeProp::Derived(error.into())
show_validation=Signal::derive(|| !error.get().is_empty())
placeholder="Choose a username"
/>
</div>
}
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Tab** | Navigate to/from input |
| **Shift+Tab** | Navigate backwards |
| **Character keys** | Enter text |
| **Ctrl/Cmd+V** | Paste |
### ARIA Attributes
The component automatically manages:
- `aria-invalid` - Set to "true" when validation fails
- `aria-describedby` - References error message element
### Screen Reader Support
```rust
// Good: Label with proper association
<Label for="email">"Email"</Label>
<Input id="email" />
// Good: Descriptive placeholder
<Input placeholder="Enter your email address" />
// Good: aria-label for icon-only inputs
<Input aria_label="Search".to_string() />
// Avoid: Non-descriptive placeholders
<Input placeholder="..." /> // Screen reader says "dot dot dot"
```
---
## Signal-Managed Variant
```rust
use shadcn_ui_leptos_input::SignalManagedInput;
#[component]
pub fn FormInput() -> impl IntoView {
let state = SignalManagedInputState::new();
view! {
<SignalManagedInput
state=state
placeholder="Type something..."
/>
}
}
```
---
## CSS Classes
### Base Classes
```css
.shadcn-input {
flex h-10 w-full rounded-md border border-input
bg-background px-3 py-2 text-sm ring-offset-background
file:border-0 file:bg-transparent file:text-sm file:font-medium
placeholder:text-muted-foreground
focus-visible:outline-none focus-visible:ring-2
focus-visible:ring-ring focus-visible:ring-offset-2
disabled:cursor-not-allowed disabled:opacity-50
}
```
### Error Classes
```css
.shadcn-input--error {
border-destructive
focus-visible:ring-destructive
}
```
### Error Message Classes
```css
.input-error-message {
text-sm text-destructive
}
```
---
## TypeScript API
```typescript
interface InputProps {
value?: string;
onChange?: (value: string) => void;
placeholder?: string;
disabled?: boolean;
type?: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url';
className?: string;
id?: string;
style?: React.CSSProperties;
validator?: InputValidator;
validationError?: string;
showValidation?: boolean;
}
interface InputValidator {
validate: (value: string) => ValidationResult;
}
interface ValidationResult {
isValid: boolean;
errors: ValidationError[];
}
interface ValidationError {
code: string;
message: string;
}
export const Input: React.FC<InputProps>;
export const validationBuilders: {
required: () => ValidationRule;
minLength: (min: number) => ValidationRule;
maxLength: (max: number) => ValidationRule;
email: () => ValidationRule;
pattern: (regex: string) => ValidationRule;
};
```
---
## Best Practices
1. **Always associate labels** - Use `id` and `<label for="...">`
2. **Provide clear placeholders** - Describe the expected format
3. **Validate appropriately** - Show errors after user interaction
4. **Use correct input types** - Enables browser-specific features
5. **Consider mobile** - Use appropriate input mode keyboards
---
## See Also
- [Button](./button.md) - Submit button
- [Label](./label.md) - Form label component
- [Form](./form.md) - Form container
- [Accessibility Guide](../ACCESSIBILITY_GUIDE.md)
---
*Source: [packages/leptos/input/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/input/src/default.rs)*

View File

@@ -0,0 +1,88 @@
# Label Component API
A form label component for associating text with form controls.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-label = "0.7"
```
```rust
use shadcn_ui_leptos_label::Label;
```
---
## Component API
### Label
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `for` | `MaybeProp<String>` | `None` | ID of associated element |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `id` | `MaybeProp<String>` | `None` | Unique identifier |
| `children` | `Option<Children>` | `None` | Label text |
---
## Usage Examples
### Basic Label
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_label::Label;
use shadcn_ui_leptos_input::Input;
#[component]
pub fn MyComponent() -> impl IntoView {
view! {
<div class="space-y-2">
<Label for="email">"Email"</Label>
<Input id="email" input_type="email" />
</div>
}
}
```
---
## CSS Classes
```css
.shadcn-label {
text-sm font-medium leading-none
peer-disabled:cursor-not-allowed peer-disabled:opacity-70
}
```
---
## Accessibility
Labels must be associated with form controls using the `for` attribute matching the input's `id`.
---
## TypeScript API
```typescript
interface LabelProps {
htmlFor?: string;
className?: string;
id?: string;
children?: React.ReactNode;
}
export const Label: React.FC<LabelProps>;
```
---
*Source: [packages/leptos/label/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/label/src/default.rs)*

View File

@@ -0,0 +1,83 @@
# Lazy Loading Component API
A component that defers loading of its children until needed.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-lazy-loading = "0.7"
```
```rust
use shadcn_ui_leptos_lazy_loading::LazyLoading;
```
---
## Component API
### LazyLoading
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `fallback` | `Option<Children>` | `None` | Loading placeholder |
| `threshold` | `MaybeProp<f64>` | `0.1` | Intersection threshold |
| `children` | `Option<Children>` | `None` | Content to load |
---
## Usage Examples
### Basic Lazy Loading
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_lazy_loading::LazyLoading;
#[component]
pub fn MyComponent() -> impl IntoView {
view! {
<LazyLoading
fallback=Some(view! {
<div class="animate-pulse">"Loading..."</div>
})
>
<div class="p-4">
"This content loads when visible"
</div>
</LazyLoading>
}
}
```
---
## CSS Classes
```css
.lazy-loading {
min-h-[100px]
}
```
---
## TypeScript API
```typescript
interface LazyLoadingProps {
fallback?: React.ReactNode;
threshold?: number;
children?: React.ReactNode;
}
export const LazyLoading: React.FC<LazyLoadingProps>;
```
---
*Source: [packages/leptos/lazy-loading/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/lazy-loading/src/default.rs)*

View File

@@ -0,0 +1,147 @@
# Menubar Component API
A persistent application menu bar at the top of the screen.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-menubar = "0.7"
```
```rust
use shadcn_ui_leptos_menubar::Menubar;
```
---
## Import
```rust
use shadcn_ui_leptos_menubar::{
Menubar,
MenubarMenu,
MenubarTrigger,
MenubarContent,
MenubarItem,
MenubarLabel,
MenubarSeparator,
MenubarShortcut
};
```
---
## Component API
### Menubar
Root menu bar container.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
### MenubarMenu
Individual menu in the bar.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `String` | **Required** | Menu identifier |
### MenubarTrigger
Clickable menu trigger.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
---
## Usage Examples
### Basic Menubar
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_menubar::*;
#[component]
pub fn MyComponent() -> impl IntoView {
view! {
<Menubar>
<MenubarMenu value="file">
<MenubarTrigger>"File"</MenubarTrigger>
<MenubarContent>
<MenubarItem>"New Tab"</MenubarItem>
<MenubarItem>"New Window"</MenubarItem>
<MenubarSeparator />
<MenubarItem>"Quit"</MenubarItem>
</MenubarContent>
</MenubarMenu>
<MenubarMenu value="edit">
<MenubarTrigger>"Edit"</MenubarTrigger>
<MenubarContent>
<MenubarItem>"Undo"</MenubarItem>
<MenubarItem>"Redo"</MenubarItem>
</MenubarContent>
</MenubarMenu>
</Menubar>
}
}
```
---
## CSS Classes
```css
.menubar {
flex h-10 items-center space-x-1 rounded-md
border bg-background p-1
}
.menubar-trigger {
inline-flex items-center justify-center rounded-md
px-3 py-1.5 text-sm font-medium transition-colors
hover:bg-accent hover:text-accent-foreground
focus:bg-accent focus:text-accent-foreground
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Arrow Keys** | Navigate menus |
| **Enter/Space** | Open menu |
| **Escape** | Close menu |
---
## TypeScript API
```typescript
interface MenubarProps {
className?: string;
children?: React.ReactNode;
}
export const Menubar: React.FC<MenubarProps>;
export const MenubarMenu: React.FC<{ value: string }>;
export const MenubarTrigger: React.FC<ComponentProps>;
export const MenubarContent: React.FC<ComponentProps>;
```
---
*Source: [packages/leptos/menubar/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/menubar/src/default.rs)*

View File

@@ -0,0 +1,148 @@
# Navigation Menu Component API
A navigation menu component with support for dropdowns and keyboard navigation.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-navigation-menu = "0.7"
```
```rust
use shadcn_ui_leptos_navigation_menu::NavigationMenu;
```
---
## Import
```rust
use shadcn_ui_leptos_navigation_menu::{
NavigationMenu,
NavigationMenuList,
NavigationMenuItem,
NavigationMenuTrigger,
NavigationMenuContent,
NavigationMenuLink
};
```
---
## Component API
### NavigationMenu
Root navigation container.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `Signal<String>` | **Required** | Current active item |
| `on_change` | `Option<Callback<String>>` | `None` | Change handler |
### NavigationMenuTrigger
Clickable menu item trigger.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
### NavigationMenuContent
Dropdown content container.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
---
## Usage Examples
### Basic Navigation Menu
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_navigation_menu::*;
#[component]
pub fn MyComponent() -> impl IntoView {
let (value, set_value) = signal("home".to_string());
view! {
<NavigationMenu
value=value.into()
on_change=Some(Callback::new(move |v| set_value.set(v)))
>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuTrigger>"Products"</NavigationMenuTrigger>
<NavigationMenuContent>
<div>"Product links..."</div>
</NavigationMenuContent>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
}
}
```
---
## CSS Classes
```css
.navigation-menu {
relative flex w-full items-center justify-center
}
.navigation-menu-list {
flex flex-1 items-center justify-center space-x-1
}
.navigation-menu-trigger {
inline-flex items-center justify-center rounded-md
px-4 py-2 text-sm font-medium transition-colors
hover:bg-accent hover:text-accent-foreground
focus:bg-accent focus:text-accent-foreground
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Arrow Keys** | Navigate items |
| **Enter/Space** | Select item |
| **Escape** | Close menu |
---
## TypeScript API
```typescript
interface NavigationMenuProps {
value: string;
onChange?: (value: string) => void;
children?: React.ReactNode;
}
export const NavigationMenu: React.FC<NavigationMenuProps>;
export const NavigationMenuList: React.FC<ComponentProps>;
export const NavigationMenuItem: React.FC<ComponentProps>;
export const NavigationMenuTrigger: React.FC<ComponentProps>;
export const NavigationMenuContent: React.FC<ComponentProps>;
```
---
*Source: [packages/leptos/navigation-menu/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/navigation-menu/src/default.rs)*

View File

@@ -0,0 +1,131 @@
# Pagination Component API
A navigation component for browsing through pages of content.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-pagination = "0.7"
```
```rust
use shadcn_ui_leptos_pagination::Pagination;
```
---
## Import
```rust
use shadcn_ui_leptos_pagination::{
Pagination,
PaginationContent,
PaginationItem,
PaginationPrevious,
PaginationNext,
PaginationLink,
PaginationEllipsis
};
```
---
## Component API
### Pagination
Root container for pagination controls.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `current_page` | `Signal<usize>` | **Required** | Current page number |
| `total_pages` | `Signal<usize>` | **Required** | Total pages |
| `on_change` | `Option<Callback<usize>>` | `None` | Page change handler |
---
## Usage Examples
### Basic Pagination
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_pagination::*;
#[component]
pub fn MyComponent() -> impl IntoView {
let (current_page, set_current_page) = signal(1);
let total_pages = Signal::derive(|| 10);
view! {
<Pagination
current_page=current_page.into()
total_pages=total_pages
on_change=Some(Callback::new(move |page| set_current_page.set(page)))
>
<PaginationContent>
<PaginationItem>
<PaginationPrevious />
</PaginationItem>
<PaginationItem>
<PaginationLink page=1>"1"</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationNext />
</PaginationItem>
</PaginationContent>
</Pagination>
}
}
```
---
## CSS Classes
```css
.pagination {
flex items-center justify-between
}
.pagination-link {
inline-flex items-center justify-center
rounded-md text-sm font-medium transition-colors
hover:bg-accent hover:text-accent-foreground
}
```
---
## Accessibility
### ARIA Attributes
- `aria-label` - Pagination labels
- `aria-current="page"` - Current page indicator
---
## TypeScript API
```typescript
interface PaginationProps {
currentPage: number;
totalPages: number;
onChange?: (page: number) => void;
}
export const Pagination: React.FC<PaginationProps>;
export const PaginationContent: React.FC<ComponentProps>;
export const PaginationLink: React.FC<{ page: number }>;
export const PaginationPrevious: React.FC<ComponentProps>;
export const PaginationNext: React.FC<ComponentProps>;
```
---
*Source: [packages/leptos/pagination/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/pagination/src/default.rs)*

View File

@@ -0,0 +1,134 @@
# Popover Component API
A floating content container positioned relative to a trigger element.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-popover = "0.7"
```
```rust
use shadcn_ui_leptos_popover::Popover;
```
---
## Import
```rust
use shadcn_ui_leptos_popover::{
Popover,
PopoverTrigger,
PopoverContent
};
```
---
## Component API
### Popover
Root component managing popover state.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `open` | `Signal<bool>` | **Required** | Open state |
| `on_open_change` | `Option<Callback<bool>>` | `None` | Change handler |
### PopoverTrigger
Element that triggers the popover.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `as_child` | `Option<Callback<...>>` | `None` | Render as custom element |
### PopoverContent
The floating popover container.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `align` | `MaybeProp<Alignment>` | `Center` | Horizontal alignment |
| `side` | `MaybeProp<Side>` | `Bottom` | Placement side |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
---
## Usage Examples
### Basic Popover
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_popover::*;
#[component]
pub fn MyComponent() -> impl IntoView {
let (open, set_open) = signal(false);
view! {
<Popover
open=open.into()
on_open_change=Some(Callback::new(move |v| set_open.set(v)))
>
<PopoverTrigger>
<button>"Open popover"</button>
</PopoverTrigger>
<PopoverContent>
<p>"Popover content"</p>
</PopoverContent>
</Popover>
}
}
```
---
## CSS Classes
```css
.popover-content {
z-50 w-72 rounded-md border bg-popover
p-4 text-popover-foreground shadow-md
outline-none data-[state=open]:animate-in
data-[state=closed]:animate-out
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Escape** | Close popover |
| **Tab** | Focus within popover |
---
## TypeScript API
```typescript
interface PopoverProps {
open: boolean;
onOpenChange?: (open: boolean) => void;
children?: React.ReactNode;
}
export const Popover: React.FC<PopoverProps>;
export const PopoverTrigger: React.FC<ComponentProps>;
export const PopoverContent: React.FC<ComponentProps>;
```
---
*Source: [packages/leptos/popover/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/popover/src/default.rs)*

View File

@@ -0,0 +1,108 @@
# Progress Component API
A progress indicator component for showing completion status.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-progress = "0.7"
```
```rust
use shadcn_ui_leptos_progress::Progress;
```
---
## Component API
### Progress
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `Signal<f64>` | **Required** | Progress value (0-100) |
| `max` | `MaybeProp<f64>` | `100` | Maximum value |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `id` | `MaybeProp<String>` | `None` | Unique identifier |
---
## Usage Examples
### Basic Progress
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_progress::Progress;
#[component]
pub fn MyComponent() -> impl IntoView {
let (progress, set_progress) = signal(66.0);
view! {
<div class="space-y-2">
<Progress value=progress.into() />
<p>{format!("{}% complete", progress.get())}</p>
</div>
}
}
```
### Indeterminate Progress
```rust
view! {
<Progress value=Signal::derive(|| 0.0) class="animate-pulse" />
}
```
---
## CSS Classes
```css
.progress-root {
relative h-4 w-full overflow-hidden rounded-full
bg-secondary
}
.progress-indicator {
h-full w-full flex-1 bg-primary
transition-all
}
```
---
## Accessibility
### ARIA Attributes
- `role="progressbar"` - Progress bar role
- `aria-valuenow` - Current value
- `aria-valuemin` - Minimum value (0)
- `aria-valuemax` - Maximum value
- `aria-label` - Accessible label
---
## TypeScript API
```typescript
interface ProgressProps {
value: number;
max?: number;
className?: string;
id?: string;
}
export const Progress: React.FC<ProgressProps>;
```
---
*Source: [packages/leptos/progress/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/progress/src/default.rs)*

View File

@@ -0,0 +1,142 @@
# Radio Group Component API
A set of radio buttons for single selection from multiple options.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-radio-group = "0.7"
```
```rust
use shadcn_ui_leptos_radio_group::RadioGroup;
```
---
## Import
```rust
use shadcn_ui_leptos_radio_group::{
RadioGroup,
RadioGroupItem
};
```
---
## Component API
### RadioGroup
Root container managing radio state.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `Signal<String>` | **Required** | Selected value |
| `on_change` | `Option<Callback<String>>` | `None` | Change handler |
| `disabled` | `Signal<bool>` | `false` | Disable group |
| `name` | `MaybeProp<String>` | `None` | Form field name |
### RadioGroupItem
Individual radio option.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `String` | **Required** | Option value |
| `disabled` | `Signal<bool>` | `false` | Disable option |
| `id` | `MaybeProp<String>` | `None` | Unique identifier |
---
## Usage Examples
### Basic Radio Group
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_radio_group::*;
#[component]
pub fn MyComponent() -> impl IntoView {
let (selected, set_selected) = signal("default".to_string());
view! {
<RadioGroup
value=selected.into()
on_change=Some(Callback::new(move |v| set_selected.set(v)))
name="notification"
>
<div class="flex items-center space-x-2">
<RadioGroupItem value="default" id="r1" />
<label for="r1">"Default"</label>
</div>
<div class="flex items-center space-x-2">
<RadioGroupItem value="compact" id="r2" />
<label for="r2">"Compact"</label>
</div>
</RadioGroup>
}
}
```
---
## CSS Classes
```css
.radio-group-item {
aspect-square h-4 w-4 rounded-full border
border-primary text-primary ring-offset-background
focus:outline-none focus:ring-2 focus:ring-ring
focus:ring-offset-2 disabled:cursor-not-allowed
disabled:opacity-50
}
.radio-group-item[data-state=checked] {
border-primary text-primary
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Arrow Keys** | Navigate options |
| **Space** | Select option |
---
## TypeScript API
```typescript
interface RadioGroupProps {
value: string;
onChange?: (value: string) => void;
disabled?: boolean;
name?: string;
children?: React.ReactNode;
}
interface RadioGroupItemProps {
value: string;
disabled?: boolean;
id?: string;
}
export const RadioGroup: React.FC<RadioGroupProps>;
export const RadioGroupItem: React.FC<RadioGroupItemProps>;
```
---
*Source: [packages/leptos/radio-group/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/radio-group/src/default.rs)*

View File

@@ -0,0 +1,69 @@
# Registry Component API
A component registry for managing and accessing components.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-registry = "0.7"
```
```rust
use shadcn_ui_leptos_registry::Registry;
```
---
## Component API
### Registry
The registry provides component discovery and metadata.
---
## Usage Examples
### Using the Registry
```rust
use shadcn_ui_leptos_registry::Registry;
#[component]
pub fn MyComponent() -> impl IntoView {
// Get component metadata
let components = Registry::get_all_components();
view! {
<div>
{components.iter().map(|c| {
view! {
<div>
<h3>{c.name.clone()}</h3>
<p>{c.description.clone()}</p>
</div>
}
}).collect::<Vec<_>>()}
</div>
}
}
```
---
## TypeScript API
```typescript
export const Registry: {
getAllComponents: () => ComponentMetadata[];
getComponent: (name: string) => ComponentMetadata | null;
};
```
---
*Source: [packages/leptos/registry/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/registry/src/default.rs)*

View File

@@ -0,0 +1,132 @@
# Resizable Component API
A container with resizable panels.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-resizable = "0.7"
```
```rust
use shadcn_ui_leptos_resizable::Resizable;
```
---
## Import
```rust
use shadcn_ui_leptos_resizable::{
Resizable,
ResizablePanel,
ResizableHandle
};
```
---
## Component API
### Resizable
Root container for resizable layout.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `direction` | `MaybeProp<Direction>` | `Horizontal` | Resize direction |
### ResizablePanel
Individual resizable panel.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `id` | `String` | **Required** | Panel identifier |
| `min_size` | `MaybeProp<f64>` | `0` | Minimum size percentage |
| `default_size` | `MaybeProp<f64>` | `50` | Default size percentage |
---
## Usage Examples
### Basic Resizable
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_resizable::*;
#[component]
pub fn MyComponent() -> impl IntoView {
view! {
<Resizable>
<ResizablePanel id="panel1" default_size=MaybeProp::Derived(50.into())>
<div class="p-4">"Left panel"</div>
</ResizablePanel>
<ResizableHandle />
<ResizablePanel id="panel2" default_size=MaybeProp::Derived(50.into())>
<div class="p-4">"Right panel"</div>
</ResizablePanel>
</Resizable>
}
}
```
---
## CSS Classes
```css
.resizable {
flex
}
.resizable-panel {
overflow-hidden
}
.resizable-handle {
flex w-px bg-border hover:bg-primary/50 cursor-col-resize
}
.resizable-handle-vertical {
h-px w-full cursor-row-resize
}
```
---
## Accessibility
- `aria-resizable` - Resizable indicator
- `aria-valuenow` - Current size
- Keyboard resize support (Shift+Arrow keys)
---
## TypeScript API
```typescript
interface ResizableProps {
direction?: 'horizontal' | 'vertical';
children?: React.ReactNode;
}
interface ResizablePanelProps {
id: string;
minSize?: number;
defaultSize?: number;
}
export const Resizable: React.FC<ResizableProps>;
export const ResizablePanel: React.FC<ResizablePanelProps>;
export const ResizableHandle: React.FC<ComponentProps>;
```
---
*Source: [packages/leptos/resizable/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/resizable/src/default.rs)*

View File

@@ -0,0 +1,97 @@
# Scroll Area Component API
A container with custom styled scrollbars.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-scroll-area = "0.7"
```
```rust
use shadcn_ui_leptos_scroll_area::ScrollArea;
```
---
## Component API
### ScrollArea
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Scrollable content |
---
## Usage Examples
### Basic Scroll Area
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_scroll_area::ScrollArea;
#[component]
pub fn MyComponent() -> impl IntoView {
view! {
<ScrollArea class="h-72 w-48 rounded-md border">
<div class="p-4">
<p>"Long content that scrolls..."</p>
</div>
</ScrollArea>
}
}
```
---
## CSS Classes
```css
.scroll-area {
overflow-auto
}
.scroll-area::-webkit-scrollbar {
width: 8px
}
.scroll-area::-webkit-scrollbar-track {
background: transparent
}
.scroll-area::-webkit-scrollbar-thumb {
background-color: hsl(var(--muted))
border-radius: 4px
}
```
---
## Accessibility
- Standard scrolling behavior maintained
- Keyboard navigation supported
---
## TypeScript API
```typescript
interface ScrollAreaProps {
className?: string;
children?: React.ReactNode;
}
export const ScrollArea: React.FC<ScrollAreaProps>;
```
---
*Source: [packages/leptos/scroll-area/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/scroll-area/src/default.rs)*

View File

@@ -0,0 +1,181 @@
# Select Component API
A dropdown select component for choosing from a list of options.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-select = "0.7"
```
```rust
use shadcn_ui_leptos_select::Select;
```
---
## Import
```rust
use shadcn_ui_leptos_select::{
Select,
SelectTrigger,
SelectContent,
SelectItem,
SelectValue,
SelectLabel,
SelectGroup,
SelectSeparator
};
```
---
## Component API
### Select
Root component for the select dropdown.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `Signal<String>` | **Required** | Selected value |
| `on_change` | `Option<Callback<String>>` | `None` | Change handler |
| `disabled` | `Signal<bool>` | `false` | Disable select |
| `placeholder` | `MaybeProp<String>` | `"Select..."` | Placeholder text |
| `children` | `Option<Children>` | `None` | Select content |
### SelectTrigger
Button that opens the dropdown.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `disabled` | `Signal<bool>` | `false` | Disable trigger |
### SelectContent
Dropdown content container.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `position` | `MaybeProp<SelectPosition>` | `Bottom` | Dropdown position |
### SelectItem
Individual selectable option.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `String` | **Required** | Option value |
| `disabled` | `Signal<bool>` | `false` | Disable option |
### SelectValue
Display area for selected value.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `placeholder` | `MaybeProp<String>` | `None` | Placeholder text |
---
## Usage Examples
### Basic Select
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_select::*;
#[component]
pub fn MyComponent() -> impl IntoView {
let (selected, set_selected) = signal("apple".to_string());
view! {
<Select
value=selected.into()
on_change=Some(Callback::new(move |value| {
set_selected.set(value);
}))
>
<SelectTrigger>
<SelectValue placeholder="Choose a fruit" />
</SelectTrigger>
<SelectContent>
<SelectItem value="apple">"Apple"</SelectItem>
<SelectItem value="banana">"Banana"</SelectItem>
<SelectItem value="orange">"Orange"</SelectItem>
</SelectContent>
</Select>
}
}
```
---
## CSS Classes
```css
.select-trigger {
flex h-10 w-full items-center justify-between
rounded-md border border-input bg-background px-3 py-2
text-sm ring-offset-background placeholder:text-muted-foreground
focus:outline-none focus:ring-2 focus:ring-ring
focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50
}
.select-content {
relative z-50 min-w-[8rem] overflow-hidden rounded-md
border bg-popover text-popover-foreground shadow-md
}
.select-item {
relative flex w-full cursor-pointer select-none
items-center rounded-sm py-1.5 pl-8 pr-2 text-sm
outline-none focus:bg-accent focus:text-accent-foreground
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Arrow Down** | Next option |
| **Arrow Up** | Previous option |
| **Enter** | Select option |
| **Escape** | Close dropdown |
---
## TypeScript API
```typescript
interface SelectProps {
value: string;
onChange?: (value: string) => void;
disabled?: boolean;
placeholder?: string;
children?: React.ReactNode;
}
export const Select: React.FC<SelectProps>;
export const SelectTrigger: React.FC<ComponentProps>;
export const SelectContent: React.FC<ComponentProps>;
export const SelectItem: React.FC<{ value: string; disabled?: boolean; children: React.ReactNode }>;
export const SelectValue: React.FC<{ placeholder?: string }>;
```
---
*Source: [packages/leptos/select/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/select/src/default.rs)*

View File

@@ -0,0 +1,117 @@
# Separator Component API
A visual separator/divider component for organizing content.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-separator = "0.7"
```
```rust
use shadcn_ui_leptos_separator::Separator;
```
---
## Component API
### Separator
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `orientation` | `MaybeProp<Orientation>` | `Horizontal` | Line direction |
| `decorative` | `Signal<bool>` | `true` | Decorative (no label) |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
### Orientation
```rust
pub enum Orientation {
Horizontal,
Vertical,
}
```
---
## Usage Examples
### Horizontal Separator
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_separator::*;
#[component]
pub fn MyComponent() -> impl IntoView {
view! {
<div>
<p>"Content above"</p>
<Separator />
<p>"Content below"</p>
</div>
}
}
```
### Vertical Separator
```rust
view! {
<div class="flex items-center gap-4">
<span>"Item 1"</span>
<Separator orientation=Orientation::Vertical class="h-8" />
<span>"Item 2"</span>
</div>
}
```
---
## CSS Classes
```css
.separator {
shrink-0 bg-border
}
.separator-horizontal {
h-px w-full
}
.separator-vertical {
h-full w-px
}
```
---
## Accessibility
### ARIA Attributes
- `role="separator"` - Separator role
- `aria-orientation` - Orientation (when decorative=false)
---
## TypeScript API
```typescript
interface SeparatorProps {
orientation?: 'horizontal' | 'vertical';
decorative?: boolean;
className?: string;
}
export const Separator: React.FC<SeparatorProps>;
```
---
*Source: [packages/leptos/separator/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/separator/src/default.rs)*

View File

@@ -0,0 +1,151 @@
# Sheet Component API
A side panel that slides in from the edge of the screen.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-sheet = "0.7"
```
```rust
use shadcn_ui_leptos_sheet::Sheet;
```
---
## Import
```rust
use shadcn_ui_leptos_sheet::{
Sheet,
SheetTrigger,
SheetContent,
SheetHeader,
SheetTitle,
SheetDescription,
SheetFooter,
SheetClose
};
```
---
## Component API
### Sheet
Root component managing sheet state.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `open` | `Signal<bool>` | **Required** | Open state |
| `on_open_change` | `Option<Callback<bool>>` | `None` | Change handler |
### SheetContent
The sliding panel container.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `side` | `MaybeProp<Side>` | `Right` | Which side to slide from |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
### Side
```rust
pub enum Side {
Top,
Right,
Bottom,
Left,
}
```
---
## Usage Examples
### Basic Sheet
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_sheet::*;
#[component]
pub fn MyComponent() -> impl IntoView {
let (open, set_open) = signal(false);
view! {
<Sheet
open=open.into()
on_open_change=Some(Callback::new(move |v| set_open.set(v)))
>
<SheetTrigger>
<button>"Open Sheet"</button>
</SheetTrigger>
<SheetContent>
<SheetHeader>
<SheetTitle>"Sheet Title"</SheetTitle>
</SheetHeader>
<div class="py-4">
"Sheet content goes here"
</div>
</SheetContent>
</Sheet>
}
}
```
---
## CSS Classes
```css
.sheet-content {
fixed z-50 gap-4 bg-background p-6 shadow-lg
transition ease-in-out data-[state=open]:animate-in
data-[state=closed]:animate-out
}
.sheet-content[data-side=right] {
inset-y-0 right-0 h-full w-3/4 border-l
data-[state=closed]:slide-out-to-right
data-[state=open]:slide-in-from-right
sm:max-w-sm
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Escape** | Close sheet |
---
## TypeScript API
```typescript
interface SheetProps {
open: boolean;
onOpenChange?: (open: boolean) => void;
children?: React.ReactNode;
}
export const Sheet: React.FC<SheetProps>;
export const SheetTrigger: React.FC<ComponentProps>;
export const SheetContent: React.FC<{ side?: 'top' | 'right' | 'bottom' | 'left' }>;
```
---
*Source: [packages/leptos/sheet/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/sheet/src/default.rs)*

View File

@@ -0,0 +1,105 @@
# Skeleton Component API
A loading placeholder component for content that is still loading.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-skeleton = "0.7"
```
```rust
use shadcn_ui_leptos_skeleton::Skeleton;
```
---
## Component API
### Skeleton
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `width` | `MaybeProp<String>` | `None` | Custom width |
| `height` | `MaybeProp<String>` | `None` | Custom height |
---
## Usage Examples
### Basic Skeleton
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_skeleton::Skeleton;
#[component]
pub fn MyComponent() -> impl IntoView {
view! {
<Skeleton />
}
}
```
### Card Skeleton
```rust
view! {
<div class="space-y-4">
<Skeleton class="h-12 w-12 rounded-full" />
<Skeleton class="h-4 w-[250px]" />
<Skeleton class="h-4 w-[200px]" />
</div>
}
```
### Custom Size
```rust
view! {
<Skeleton width="100px" height="100px" />
}
```
---
## CSS Classes
```css
.skeleton {
animate-pulse rounded-md bg-muted
}
```
---
## Accessibility
### ARIA Attributes
- `role="status"` - Status for screen readers
- `aria-live="polite"` - Announces to screen readers
- Hidden from assistive technology (loading placeholder)
---
## TypeScript API
```typescript
interface SkeletonProps {
className?: string;
width?: string;
height?: string;
}
export const Skeleton: React.FC<SkeletonProps>;
```
---
*Source: [packages/leptos/skeleton/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/skeleton/src/default.rs)*

View File

@@ -0,0 +1,123 @@
# Slider Component API
A slider control for selecting values within a range.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-slider = "0.7"
```
```rust
use shadcn_ui_leptos_slider::Slider;
```
---
## Component API
### Slider
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `Signal<Vec<f64>>` | **Required** | Current value(s) |
| `on_change` | `Option<Callback<Vec<f64>>>` | `None` | Change handler |
| `min` | `MaybeProp<f64>` | `0` | Minimum value |
| `max` | `MaybeProp<f64>` | `100` | Maximum value |
| `step` | `MaybeProp<f64>` | `1` | Step increment |
| `disabled` | `Signal<bool>` | `false` | Disable slider |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
---
## Usage Examples
### Basic Slider
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_slider::Slider;
#[component]
pub fn MyComponent() -> impl IntoView {
let (value, set_value) = signal(vec![50.0]);
view! {
<div class="space-y-4">
<Slider
value=value.into()
on_change=Some(Callback::new(move |v| set_value.set(v)))
/>
<p>{format!("Value: {}", value.get()[0])}</p>
</div>
}
}
```
---
## CSS Classes
```css
.slider-root {
relative flex w-full touch-none
select-none items-center
}
.slider-track {
relative h-2 w-full grow overflow-hidden
rounded-full bg-secondary
}
.slider-fill {
absolute h-full bg-primary
}
.slider-thumb {
block h-5 w-5 rounded-full border-2
border-primary bg-background ring-offset-background
transition-colors focus-visible:outline-none
focus-visible:ring-2 focus-visible:ring-ring
focus-visible:ring-offset-2 disabled:pointer-events-none
disabled:opacity-50
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Arrow Right** | Increase value |
| **Arrow Left** | Decrease value |
| **Home** | Minimum value |
| **End** | Maximum value |
---
## TypeScript API
```typescript
interface SliderProps {
value: number[];
onChange?: (value: number[]) => void;
min?: number;
max?: number;
step?: number;
disabled?: boolean;
className?: string;
}
export const Slider: React.FC<SliderProps>;
```
---
*Source: [packages/leptos/slider/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/slider/src/default.rs)*

View File

@@ -0,0 +1,196 @@
# Switch Component API
A toggle switch component for binary on/off states.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-switch = "0.7"
```
```rust
use shadcn_ui_leptos_switch::Switch;
```
---
## Import
```rust
use shadcn_ui_leptos_switch::{
Switch,
SwitchRoot,
SwitchThumb,
SwitchLabel,
SwitchVariant,
SwitchSize
};
```
---
## Component API
### Switch
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `checked` | `Signal<bool>` | **Required** | Switch state |
| `on_change` | `Option<Callback<bool>>` | `None` | Change handler |
| `variant` | `MaybeProp<SwitchVariant>` | `Default` | Visual variant |
| `size` | `MaybeProp<SwitchSize>` | `Md` | Switch size |
| `disabled` | `Signal<bool>` | `false` | Disable switch |
| `animated` | `Signal<bool>` | `true` | Enable animation |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `id` | `MaybeProp<String>` | `None` | Unique identifier |
| `style` | `Signal<Style>` | `None` | Inline styles |
### SwitchVariant
```rust
pub enum SwitchVariant {
Default, // Primary color when checked
Success, // Green when checked
Warning, // Yellow when checked
Destructive, // Red when checked
Info, // Blue when checked
}
```
### SwitchSize
```rust
pub enum SwitchSize {
Sm, // Small (h-4 w-7)
Md, // Medium (h-6 w-11)
Lg, // Large (h-8 w-14)
}
```
---
## Usage Examples
### Basic Switch
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_switch::Switch;
#[component]
pub fn MyComponent() -> impl IntoView {
let (enabled, set_enabled) = signal(false);
view! {
<div class="flex items-center space-x-2">
<Switch
checked=enabled.into()
on_change=Some(Callback::new(move |is_checked| {
set_enabled.set(is_checked);
}))
id="notifications"
/>
<label for="notifications">"Enable notifications"</label>
</div>
}
}
```
### Variants
```rust
view! {
<div class="space-y-4">
<Switch variant=SwitchVariant::Default checked=Signal::derive(|| true) />
<Switch variant=SwitchVariant::Success checked=Signal::derive(|| true) />
<Switch variant=SwitchVariant::Warning checked=Signal::derive(|| true) />
<Switch variant=SwitchVariant::Destructive checked=Signal::derive(|| true) />
<Switch variant=SwitchVariant::Info checked=Signal::derive(|| true) />
</div>
}
```
### Sizes
```rust
view! {
<div class="flex items-center gap-4">
<Switch size=SwitchSize::Sm checked=Signal::derive(|| true) />
<Switch size=SwitchSize::Md checked=Signal::derive(|| true) />
<Switch size=SwitchSize::Lg checked=Signal::derive(|| true) />
</div>
}
```
---
## CSS Classes
```css
.switch-root {
peer inline-flex h-6 w-11 shrink-0 cursor-pointer
items-center rounded-full border-2 border-transparent
transition-colors focus-visible:outline-none
focus-visible:ring-2 focus-visible:ring-ring
focus-visible:ring-offset-2 disabled:cursor-not-allowed
disabled:opacity-50
}
.switch-root[data-state="checked"] {
bg-primary
}
.switch-root[data-state="unchecked"] {
bg-input
}
.switch-thumb {
pointer-events-none block h-5 w-5 rounded-full
bg-background shadow-lg ring-0 transition-transform
}
.switch-thumb[data-state="checked"] {
translate-x-5
}
.switch-thumb[data-state="unchecked"] {
translate-x-0
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Space** | Toggle switch |
---
## TypeScript API
```typescript
interface SwitchProps {
checked: boolean;
onChange?: (checked: boolean) => void;
variant?: 'default' | 'success' | 'warning' | 'destructive' | 'info';
size?: 'sm' | 'md' | 'lg';
disabled?: boolean;
animated?: boolean;
className?: string;
id?: string;
}
export const Switch: React.FC<SwitchProps>;
```
---
*Source: [packages/leptos/switch/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/switch/src/default.rs)*

View File

@@ -0,0 +1,226 @@
# Table Component API
A table component for displaying structured data in rows and columns.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-table = "0.7"
```
```rust
use shadcn_ui_leptos_table::Table;
```
---
## Import
```rust
use shadcn_ui_leptos_table::{
Table,
TableHeader,
TableBody,
TableFooter,
TableRow,
TableHead,
TableCell,
TableCaption
};
```
---
## Component API
### Table
Root table container.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Table content |
### TableHeader
Header section containing column headings.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Header content |
### TableBody
Main body containing data rows.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Body content |
### TableFooter
Footer section for summaries or pagination.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Footer content |
### TableRow
Single row in the table.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Row content |
### TableHead
Column header cell.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Header text |
### TableCell
Data cell.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Cell content |
### TableCaption
Table caption/title.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Caption text |
---
## Usage Examples
### Basic Table
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_table::*;
#[component]
pub fn MyComponent() -> impl IntoView {
view! {
<Table>
<TableCaption>"A list of your recent invoices."</TableCaption>
<TableHeader>
<TableRow>
<TableHead>"Invoice"</TableHead>
<TableHead>"Status"</TableHead>
<TableHead>"Amount"</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>"INV001"</TableCell>
<TableCell>"Paid"</TableCell>
<TableCell>"$250.00"</TableCell>
</TableRow>
<TableRow>
<TableCell>"INV002"</TableCell>
<TableCell>"Pending"</TableCell>
<TableCell>"$150.00"</TableCell>
</TableRow>
</TableBody>
</Table>
}
}
```
---
## CSS Classes
```css
.table {
w-full caption-bottom text-sm
}
.table-header {
border-b
}
.table-body {
&[data-truncate=true] tr {
@apply last:border-b;
}
}
.table-footer {
border-t bg-muted/50 font-medium
}
.table-row {
border-b transition-colors hover:bg-muted/50
}
.table-head {
h-10 px-2 text-left align-middle font-medium
text-muted-foreground [&:has([role=checkbox])]:pr-0
}
.table-cell {
p-2 align-middle [&:has([role=checkbox])]:pr-0
}
.table-caption {
mt-4 text-sm text-muted-foreground
}
```
---
## Accessibility
### ARIA Attributes
- `role="table"` - Table role
- `role="row"` - Row role
- `role="columnheader"` - Header cell role
- `role="cell"` - Data cell role
- Scope attributes for headers
---
## TypeScript API
```typescript
interface TableProps {
className?: string;
children?: React.ReactNode;
}
export const Table: React.FC<TableProps>;
export const TableHeader: React.FC<ComponentProps>;
export const TableBody: React.FC<ComponentProps>;
export const TableFooter: React.FC<ComponentProps>;
export const TableRow: React.FC<ComponentProps>;
export const TableHead: React.FC<ComponentProps>;
export const TableCell: React.FC<ComponentProps>;
export const TableCaption: React.FC<ComponentProps>;
```
---
*Source: [packages/leptos/table/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/table/src/default.rs)*

305
docs/components/api/tabs.md Normal file
View File

@@ -0,0 +1,305 @@
# Tabs Component API
A tabbed interface component for organizing content into separate panels.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-tabs = "0.7"
```
```rust
use shadcn_ui_leptos_tabs::Tabs;
```
---
## Import
```rust
// Default theme
use shadcn_ui_leptos_tabs::{
Tabs,
TabsList,
TabsTrigger,
TabsContent
};
// New York theme
use shadcn_ui_leptos_tabs::{
Tabs as TabsNewYork,
TabsList as TabsListNewYork,
TabsTrigger as TabsTriggerNewYork,
TabsContent as TabsContentNewYork
};
// Signal-managed variant
use shadcn_ui_leptos_tabs::{
SignalManagedTabs,
SignalManagedTabsState
};
```
---
## Component API
### Tabs
Root container that manages tab state.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `Signal<String>` | **Required** | Currently active tab value |
| `on_change` | `Option<Callback<String>>` | `None` | Called when tab changes |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `id` | `MaybeProp<String>` | `None` | Unique identifier |
| `children` | `Option<Children>` | `None` | Tab content |
### TabsList
Container for tab triggers.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Tab triggers |
### TabsTrigger
Individual tab button.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `String` | **Required** | Unique identifier for tab |
| `disabled` | `Signal<bool>` | `false` | Disable tab |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Tab label |
### TabsContent
Content panel for a tab.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `String` | **Required** | Matches trigger value |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `children` | `Option<Children>` | `None` | Panel content |
---
## Usage Examples
### Basic Tabs
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_tabs::*;
#[component]
pub fn MyComponent() -> impl IntoView {
let (active_tab, set_active_tab) = signal("account".to_string());
view! {
<Tabs
value=active_tab.into()
on_change=Some(Callback::new(move |value| {
set_active_tab.set(value);
}))
>
<TabsList>
<TabsTrigger value="account">"Account"</TabsTrigger>
<TabsTrigger value="password">"Password"</TabsTrigger>
<TabsTrigger value="settings">"Settings"</TabsTrigger>
</TabsList>
<TabsContent value="account">
"Account settings content"
</TabsContent>
<TabsContent value="password">
"Password settings content"
</TabsContent>
<TabsContent value="settings">
"General settings content"
</TabsContent>
</Tabs>
}
}
```
### Vertical Tabs
```rust
view! {
<div class="flex gap-4">
<TabsList class="flex-col h-full">
<TabsTrigger value="tab1">"Tab 1"</TabsTrigger>
<TabsTrigger value="tab2">"Tab 2"</TabsTrigger>
<TabsTrigger value="tab3">"Tab 3"</TabsTrigger>
</TabsList>
<div class="flex-1">
<TabsContent value="tab1">"Content 1"</TabsContent>
<TabsContent value="tab2">"Content 2"</TabsContent>
<TabsContent value="tab3">"Content 3"</TabsContent>
</div>
</div>
}
```
### Disabled Tabs
```rust
view! {
<Tabs value=active_tab.into()>
<TabsList>
<TabsTrigger value="enabled">"Enabled Tab"</TabsTrigger>
<TabsTrigger
value="disabled"
disabled=Signal::derive(|| true)
>
"Disabled Tab"
</TabsTrigger>
</TabsList>
<TabsContent value="enabled">"Content"</TabsContent>
</Tabs>
}
```
### With Icons
```rust
view! {
<Tabs value=active_tab.into()>
<TabsList>
<TabsTrigger value="home">
<span class="mr-2">"</span>
"Home"
</TabsTrigger>
<TabsTrigger value="profile">
<span class="mr-2">"</span>
"Profile"
</TabsTrigger>
<TabsTrigger value="settings">
<span class="mr-2">"</span>
"Settings"
</TabsTrigger>
</TabsList>
// ... content
</Tabs>
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Arrow Right** | Next tab |
| **Arrow Left** | Previous tab |
| **Home** | First tab |
| **End** | Last tab |
| **Enter/Space** | Activate tab |
### ARIA Attributes
The component automatically manages:
- `role="tablist"` - TabsList container
- `role="tab"` - TabsTrigger elements
- `role="tabpanel"` - TabsContent elements
- `aria-selected` - Current tab state
- `aria-controls` - Panel association
- `aria-labelledby` - Label association
---
## CSS Classes
```css
.tabs-list {
inline-flex h-10 items-center justify-center
rounded-md bg-muted p-1 text-muted-foreground
}
.tabs-trigger {
inline-flex items-center justify-center
whitespace-nowrap rounded-sm px-3 py-1.5
text-sm font-medium ring-offset-background
transition-all focus-visible:outline-none
focus-visible:ring-2 focus-visible:ring-ring
focus-visible:ring-offset-2
disabled:pointer-events-none disabled:opacity-50
}
.tabs-trigger[data-state="active"] {
bg-background text-foreground shadow-sm
}
.tabs-content {
mt-2 ring-offset-background
focus-visible:outline-none focus-visible:ring-2
focus-visible:ring-ring focus-visible:ring-offset-2
}
```
---
## TypeScript API
```typescript
interface TabsProps {
value: string;
onChange?: (value: string) => void;
className?: string;
children?: React.ReactNode;
}
interface TabsTriggerProps {
value: string;
disabled?: boolean;
className?: string;
children?: React.ReactNode;
}
interface TabsContentProps {
value: string;
className?: string;
children?: React.ReactNode;
}
export const Tabs: React.FC<TabsProps>;
export const TabsList: React.FC<ComponentProps>;
export const TabsTrigger: React.FC<TabsTriggerProps>;
export const TabsContent: React.FC<TabsContentProps>;
```
---
## Best Practices
1. **Keep tab labels short** - 1-2 words maximum
2. **Use descriptive values** - Match content purpose
3. **Limit tab count** - 3-7 tabs ideal
4. **Maintain content consistency** - Similar structure per tab
5. **Consider mobile** - Horizontal scroll or stack
---
## See Also
- [Accordion](./accordion.md) - Vertical alternative
- [Separator](./separator.md) - Visual dividers
---
*Source: [packages/leptos/tabs/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/tabs/src/default.rs)*

View File

@@ -0,0 +1,108 @@
# Textarea Component API
A multi-line text input component for longer content.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-textarea = "0.7"
```
```rust
use shadcn_ui_leptos_textarea::Textarea;
```
---
## Component API
### Textarea
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `MaybeProp<String>` | `None` | Current value |
| `on_change` | `Option<Callback<String>>` | `None` | Change handler |
| `placeholder` | `MaybeProp<String>` | `None` | Placeholder text |
| `disabled` | `Signal<bool>` | `false` | Disable textarea |
| `rows` | `MaybeProp<usize>` | `3` | Number of rows |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
| `id` | `MaybeProp<String>` | `None` | Unique identifier |
| `style` | `Signal<Style>` | `None` | Inline styles |
---
## Usage Examples
### Basic Textarea
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_textarea::Textarea;
#[component]
pub fn MyComponent() -> impl IntoView {
let (text, set_text) = signal(String::new());
view! {
<Textarea
value=MaybeProp::Derived(text.into())
on_change=Some(Callback::new(move |value| {
set_text.set(value);
}))
placeholder="Enter your message"
rows=MaybeProp::Derived(5.into())
/>
}
}
```
---
## CSS Classes
```css
.shadcn-textarea {
flex min-h-[80px] w-full rounded-md border border-input
bg-background px-3 py-2 text-sm ring-offset-background
placeholder:text-muted-foreground focus-visible:outline-none
focus-visible:ring-2 focus-visible:ring-ring
focus-visible:ring-offset-2 disabled:cursor-not-allowed
disabled:opacity-50
}
```
---
## Accessibility
### ARIA Attributes
- `aria-label` - Accessible label
- `aria-describedby` - Description reference
- `aria-invalid` - Validation state
---
## TypeScript API
```typescript
interface TextareaProps {
value?: string;
onChange?: (value: string) => void;
placeholder?: string;
disabled?: boolean;
rows?: number;
className?: string;
id?: string;
}
export const Textarea: React.FC<TextareaProps>;
```
---
*Source: [packages/leptos/textarea/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/textarea/src/default.rs)*

View File

@@ -0,0 +1,150 @@
# Toast Component API
A temporary notification component for displaying brief messages.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-toast = "0.7"
```
```rust
use shadcn_ui_leptos_toast::Toast;
```
---
## Import
```rust
use shadcn_ui_leptos_toast::{
Toast,
ToastProvider,
ToastTitle,
ToastDescription,
ToastAction,
ToastClose,
ToastVariant
};
```
---
## Component API
### ToastProvider
Context provider for toast notifications.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `children` | `Option<Children>` | `None` | App content |
### Toast
Individual toast notification.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `variant` | `MaybeProp<ToastVariant>` | `Default` | Toast style |
| `title` | `MaybeProp<String>` | `None` | Toast title |
| `description` | `MaybeProp<String>` | `None` | Toast description |
| `duration` | `MaybeProp<u64>` | `5000` | Auto-close duration (ms) |
| `on_close` | `Option<Callback<()>>` | `None` | Close callback |
### ToastVariant
```rust
pub enum ToastVariant {
Default, // Neutral styling
Destructive, // Red for errors
Success, // Green for success
}
```
---
## Usage Examples
### Basic Toast
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_toast::*;
#[component]
pub fn MyComponent() -> impl IntoView {
view! {
<ToastProvider>
<div>
<button on:click=move |_| {
// Show toast
}>"Show Toast"</button>
</div>
</ToastProvider>
}
}
```
---
## CSS Classes
```css
.toast {
group pointer-events-auto relative flex w-full
items-center justify-between space-x-4 overflow-hidden
rounded-md border p-6 pr-8 shadow-lg transition-all
}
.toast-default {
border bg-background text-foreground
}
.toast-destructive {
border-destructive bg-destructive text-destructive-foreground
}
.toast-success {
border-success bg-success text-success-foreground
}
```
---
## Accessibility
### ARIA Attributes
- `role="status"` - Status role
- `aria-live="polite"` - Polite announcements
- `aria-atomic="true"` - Complete content reading
---
## TypeScript API
```typescript
interface ToastProps {
variant?: 'default' | 'destructive' | 'success';
title?: string;
description?: string;
duration?: number;
onClose?: () => void;
}
export const Toast: React.FC<ToastProps>;
export const ToastProvider: React.FC<{ children: React.ReactNode }>;
export const ToastTitle: React.FC<ComponentProps>;
export const ToastDescription: React.FC<ComponentProps>;
export const ToastAction: React.FC<ButtonProps>;
export const ToastClose: React.FC<ButtonProps>;
```
---
*Source: [packages/leptos/toast/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/toast/src/default.rs)*

View File

@@ -0,0 +1,115 @@
# Toggle Component API
A two-state button that can be on or off.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-toggle = "0.7"
```
```rust
use shadcn_ui_leptos_toggle::Toggle;
```
---
## Component API
### Toggle
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `pressed` | `Signal<bool>` | **Required** | Toggle state |
| `on_change` | `Option<Callback<bool>>` | `None` | Change handler |
| `disabled` | `Signal<bool>` | `false` | Disable toggle |
| `variant` | `MaybeProp<ToggleVariant>` | `Default` | Visual style |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
### ToggleVariant
```rust
pub enum ToggleVariant {
Default,
Outline,
}
```
---
## Usage Examples
### Basic Toggle
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_toggle::Toggle;
#[component]
pub fn MyComponent() -> impl IntoView {
let (pressed, set_pressed) = signal(false);
view! {
<Toggle
pressed=pressed.into()
on_change=Some(Callback::new(move |v| set_pressed.set(v)))
>
"Toggle me"
</Toggle>
}
}
```
---
## CSS Classes
```css
.toggle {
inline-flex items-center justify-center rounded-md
text-sm font-medium transition-colors
hover:bg-muted hover:text-muted-foreground
focus-visible:outline-none focus-visible:ring-2
focus-visible:ring-ring disabled:pointer-events-none
disabled:opacity-50
}
.toggle[data-state=on] {
bg-accent text-accent-foreground
}
```
---
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| **Enter** | Toggle state |
| **Space** | Toggle state |
---
## TypeScript API
```typescript
interface ToggleProps {
pressed: boolean;
onChange?: (pressed: boolean) => void;
disabled?: boolean;
variant?: 'default' | 'outline';
className?: string;
}
export const Toggle: React.FC<ToggleProps>;
```
---
*Source: [packages/leptos/toggle/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/toggle/src/default.rs)*

View File

@@ -0,0 +1,127 @@
# Tooltip Component API
A floating label that displays information when hovering over an element.
---
## Installation
```toml
# Cargo.toml
[dependencies]
shadcn-ui-leptos-tooltip = "0.7"
```
```rust
use shadcn_ui_leptos_tooltip::Tooltip;
```
---
## Import
```rust
use shadcn_ui_leptos_tooltip::{
Tooltip,
TooltipTrigger,
TooltipContent
};
```
---
## Component API
### Tooltip
Root component managing tooltip state.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `open` | `Signal<bool>` | **Required** | Open state |
| `delay_duration` | `MaybeProp<u64>` | `400` | Show delay (ms) |
### TooltipTrigger
Element that triggers the tooltip on hover.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `as_child` | `Option<Callback<...>>` | `None` | Render as custom element |
### TooltipContent
The floating tooltip container.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `side` | `MaybeProp<Side>` | `Top` | Placement side |
| `class` | `MaybeProp<String>` | `None` | Additional CSS classes |
---
## Usage Examples
### Basic Tooltip
```rust
use leptos::prelude::*;
use shadcn_ui_leptos_tooltip::*;
#[component]
pub fn MyComponent() -> impl IntoView {
let (open, set_open) = signal(false);
view! {
<Tooltip open=open.into()>
<TooltipTrigger>
<button>"Hover me"</button>
</TooltipTrigger>
<TooltipContent>
<p>"Tooltip content"</p>
</TooltipContent>
</Tooltip>
}
}
```
---
## CSS Classes
```css
.tooltip-content {
z-50 overflow-hidden rounded-md bg-primary
px-3 py-1.5 text-xs text-primary-foreground
animate-in fade-in-0 zoom-in-95
}
```
---
## Accessibility
### ARIA Attributes
- `role="tooltip"` - Tooltip role
- `aria-describedby` - References tooltip content
---
## TypeScript API
```typescript
interface TooltipProps {
open: boolean;
delayDuration?: number;
children?: React.ReactNode;
}
export const Tooltip: React.FC<TooltipProps>;
export const TooltipTrigger: React.FC<ComponentProps>;
export const TooltipContent: React.FC<ComponentProps>;
```
---
*Source: [packages/leptos/tooltip/src/default.rs](https://github.com/yourusername/leptos-shadcn-ui/blob/main/packages/leptos/tooltip/src/default.rs)*