Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 09:05:04 +08:00
commit 7afdd6601b
69 changed files with 9552 additions and 0 deletions

77
docs/components/avatar.md Normal file
View File

@@ -0,0 +1,77 @@
# Avatar Component Documentation
## Overview
The Avatar component presents a circular image element designed for representing users, with built-in fallback functionality. It extends Radix UI's Avatar primitive and includes server-side rendering support plus enhanced features for grouping multiple avatars.
## Component Parts
### Avatar (Root)
The main container for displaying user avatars.
**Props:**
- `className` (string): Additional CSS classes
- `children` (ReactNode): AvatarImage and AvatarFallback components
- Supports all Radix UI Avatar.Root props
### AvatarImage
Renders the user's profile image with automatic fallback handling.
**Props:**
- `src` (string): Image source URL
- `alt` (string): Alternative text for accessibility
- `className` (string): Custom CSS classes
- Inherits all Radix UI Avatar.Image props
### AvatarFallback
Shows fallback content when the image fails to load.
**Props:**
- `className` (string): Custom styling
- `children` (ReactNode): Fallback content, typically initials
- Supports all Radix UI Avatar.Fallback props
### AvatarGroup
Groups multiple avatars in a stacked arrangement with configurable spacing.
**Props:**
- `children` (ReactNode): Avatar components to display
- `className` (string): Custom CSS classes
- `spacing` ("tight" | "normal" | "loose"): Controls avatar spacing
- `max` (number): Maximum avatars shown before displaying "+N" indicator
**Spacing Options:**
- **tight**: Closest together (`-space-x-1.5`)
- **normal**: Default spacing (`-space-x-1`)
- **loose**: Most space between (`-space-x-0.45`)
## Usage Examples
### Basic Avatar
```jsx
<Avatar>
<AvatarImage src="/images/shadcn.png" alt="@shadcn" />
<AvatarFallback>CN</AvatarFallback>
</Avatar>
```
### Custom Sizes
```jsx
<div className="flex items-center gap-4">
<Avatar className="size-8">
<AvatarImage src="/images/shadcn.png" alt="@shadcn" />
<AvatarFallback className="text-xs">CN</AvatarFallback>
</Avatar>
<Avatar className="size-12">
<AvatarImage src="/images/shadcn.png" alt="@shadcn" />
<AvatarFallback>CN</AvatarFallback>
</Avatar>
<Avatar className="size-16">
<AvatarImage src="/images/shadcn.png" alt="@shadcn" />
<AvatarFallback className="text-lg">CN</AvatarFallback>
</Avatar>
</div>
```
### Avatar Groups with Spacing Variants
Groups can implement tight, normal, or loose spacing configurations by adjusting the `spacing` prop on the `AvatarGroup` component.

68
docs/components/badge.md Normal file
View File

@@ -0,0 +1,68 @@
# Badge Component Documentation
## Overview
The Badge component displays a badge or badge-like visual element. It extends standard span functionality with customizable variants and shapes.
## Type Definition
```typescript
interface BadgeProps extends ComponentProps<"span">, VariantProps<typeof badgeVariants> {
asChild?: boolean;
variant?: "default" | "secondary" | "destructive" | "success" | "warning" | "accent";
type?: "default" | "circle" | "dot";
}
```
## Properties
| Property | Type | Default | Purpose |
|----------|------|---------|---------|
| `variant` | `'default' \| 'secondary' \| 'destructive' \| 'success' \| 'warning' \| 'accent'` | `'default'` | Determines the visual styling |
| `type` | `'default' \| 'circle' \| 'dot'` | `'default'` | Controls shape and layout presentation |
| `asChild` | `boolean` | `false` | Enables `Slot` rendering for child element styling |
| span props | `ComponentProps<'span'>` | — | All native HTML span attributes supported |
## Basic Examples
Simple badge variants:
```jsx
<Badge>Default</Badge>
<Badge variant="success">Deployed</Badge>
<Badge type="circle">3</Badge>
<Badge type="dot" />
```
## Usage Patterns
**Variant showcase:**
```jsx
<Badge>Badge</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="destructive">Destructive</Badge>
<Badge variant="success">Success</Badge>
<Badge variant="warning">warning</Badge>
```
**Circular badge indicators:**
```jsx
<Badge type="circle">3</Badge>
<Badge variant="secondary" type="circle">3</Badge>
<Badge variant="destructive" type="circle">3</Badge>
<Badge variant="success" type="circle">3</Badge>
<Badge variant="warning" type="circle">3</Badge>
```
**Dot indicators:**
```jsx
<Badge type="dot" />
<Badge variant="secondary" type="dot" />
<Badge variant="destructive" type="dot" />
<Badge variant="success" type="dot" />
<Badge variant="warning" type="dot" />
```
## References
- [Radix UI Badge Documentation](https://www.radix-ui.com/primitives/docs/components/badge)
- [API Reference](https://www.radix-ui.com/primitives/docs/components/badge#api-reference)

144
docs/components/button.md Normal file
View File

@@ -0,0 +1,144 @@
# Button Component Documentation
## Overview
The Button component is a fundamental UI element used to trigger actions or events. It supports multiple visual styles, sizes, and states for different use cases like form submission, dialog opening, action cancellation, and delete operations.
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `variant` | `'primary' \| 'secondary' \| 'destructive' \| 'ghost' \| 'link'` | `'primary'` | Visual appearance style |
| `size` | `'sm' \| 'base' \| 'lg'` | `'base'` | Button dimensions |
| `icon` | `boolean` | `false` | Optimizes spacing for icon-only buttons |
| `asChild` | `boolean` | `false` | Uses Slot to render as child component |
| ...button props | `ComponentProps<'button'>` | — | All standard HTML button attributes supported |
## Variants
### Primary
The default style for main actions:
```jsx
<Button>Primary</Button>
<Button>Primary Action</Button>
<Button icon aria-label="Primary action">
<Plus className="size-4" />
</Button>
```
### Secondary
Alternative action style:
```jsx
<Button variant="secondary">Secondary</Button>
<Button variant="secondary">
<Plus className="size-4 mr-2" />
Add Item
</Button>
```
### Destructive
For dangerous operations like deletion:
```jsx
<Button variant="destructive">Destructive</Button>
<Button variant="destructive">
<Trash className="size-4 mr-2" />
Delete
</Button>
```
### Ghost
Subtle action style:
```jsx
<Button variant="ghost">Ghost</Button>
<Button variant="ghost" icon>
<Settings className="size-4" />
</Button>
```
## Sizes
### Small
```jsx
<Button size="sm">Small</Button>
<Button size="sm" variant="secondary">
<Plus className="size-3 mr-1" />
Add
</Button>
```
### Default
```jsx
<Button>Default</Button>
<Button>
<Save className="size-4 mr-2" />
Save Changes
</Button>
```
### Large
```jsx
<Button size="lg">Large</Button>
<Button size="lg" className="px-8">
<ArrowRight className="size-5 mr-2" />
Get Started
</Button>
```
## Icon Buttons
Use the `icon` prop to properly space icon-only buttons across different sizes and variants:
```jsx
<Button icon size="sm" aria-label="Settings">
<Settings className="size-3" />
</Button>
<Button icon variant="secondary" aria-label="Edit">
<Edit className="size-4" />
</Button>
<Button icon variant="destructive" aria-label="Delete">
<Trash2 className="size-4" />
</Button>
```
## States
### Disabled
```jsx
<Button disabled>Disabled</Button>
<Button disabled title="Complete required fields first">
<Lock className="size-4 mr-2" />
Submit Form
</Button>
```
## Type Definition
```typescript
interface ButtonProps extends ComponentProps<"button">, VariantProps<typeof buttonVariants> {
asChild?: boolean;
variant?: "primary" | "secondary" | "destructive" | "ghost" | "link";
size?: "sm" | "md" | "lg";
icon?: boolean;
}
```
## Usage Example
```jsx
import { Button } from '@vuer-ai/vuer-uikit';
function MyComponent() {
return (
<div>
<Button>Primary Button</Button>
<Button variant="secondary">Secondary Button</Button>
<Button variant="destructive">Destructive Button</Button>
<Button size="sm">Small Button</Button>
<Button size="lg">Large Button</Button>
<Button disabled>Disabled Button</Button>
</div>
);
}
```

208
docs/components/card.md Normal file
View File

@@ -0,0 +1,208 @@
- Home
- Components
- Card
# Card
Displays a card with header, content, and footer.
## Props
This component group provides styled containers. All parts accept standard div props.
- Card: root container with size variants (sm, md, lg, xl) for padding
- CardHeader: header row with optional actions, supports size variants for gap spacing
- CardTitle: title text
- CardDescription: subdued description text
- CardAction: right-aligned action area in header
- CardContent: main content area
- CardFooter: footer area (flex container)
## Types
```
// Card component with size variants
interface CardProps extends ComponentProps<"div"> {
size?: "sm" | "md" | "lg" | "xl";
}
// CardHeader also supports size variants for gap spacing
interface CardHeaderProps extends ComponentProps<"div"> {
size?: "sm" | "md" | "lg" | "xl";
}
// All other Card components extend ComponentProps<"div">
interface CardTitleProps extends ComponentProps<"div"> {}
interface CardDescriptionProps extends ComponentProps<"div"> {}
interface CardActionProps extends ComponentProps<"div"> {}
interface CardContentProps extends ComponentProps<"div"> {}
interface CardFooterProps extends ComponentProps<"div"> {}
```
```
<Card className="w-[300px]">
<CardHeader>
<CardTitle>Card Title</CardTitle>
<CardAction>
<Button variant="link">action</Button>
</CardAction>
</CardHeader>
<CardContent>
<div className="flex flex-col my-4">
<div>CardContent...</div>
<div>CardContent...</div>
<div>CardContent...</div>
<div>CardContent...</div>
<div>CardContent...</div>
</div>
</CardContent>
<CardFooter className="flex-col gap-2">
<Button className="w-full">Footer</Button>
</CardFooter>
</Card>
```
## Sizes
The Card component supports different padding sizes, and CardHeader adjusts gap spacing accordingly:
```
// Small card with reduced padding and gap spacing
<Card size="sm" className="w-50">
<CardHeader size="sm">
<CardTitle>Small Card</CardTitle>
<CardAction>
<Settings className="size-4" />
</CardAction>
</CardHeader>
<CardContent className="text-uk-sm">
Compact content with smaller padding and gap.
</CardContent>
</Card>
// Large card with increased padding and gap spacing (default)
<Card size="lg" className="w-50">
<CardHeader size="lg">
<CardTitle>Large Card</CardTitle>
<CardAction>
<Settings className="size-4" />
</CardAction>
</CardHeader>
<CardContent className="text-uk-md">
More spacious content with larger padding and gap.
</CardContent>
</Card>
```
## Login Form Example
```
import { Button } from "@vuer-ai/vuer-uikit"
import {
Card,
CardAction,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@vuer-ai/vuer-uikit"
import { Input, Label } from "@vuer-ai/vuer-uikit"
<Card className="w-80">
<CardHeader>
<CardTitle>Login to your account</CardTitle>
<CardAction>
<Button variant="link">Sign Up</Button>
</CardAction>
</CardHeader>
<CardContent className="flex flex-col gap-lg pb-lg">
<CardDescription>
Enter your email below to login to your account
</CardDescription>
<form>
<div className="flex flex-col gap-6">
<div className="grid gap-2">
<Label htmlFor="email">Email</Label>
<Input
id="email"
type="email"
placeholder="m@example.com"
required
/>
</div>
<div className="grid gap-2">
<div className="flex items-center">
<Label htmlFor="password">Password</Label>
<a
href="#"
className="ml-auto inline-block text-uk-xs underline-offset-4 hover:underline"
>
Forgot your password?
</a>
</div>
<Input id="password" type="password" required />
</div>
</div>
</form>
</CardContent>
<CardFooter className="flex-col gap-2">
<Button type="submit" className="w-full">
Login
</Button>
<Button variant="outline" className="w-full">
Login with Google
</Button>
</CardFooter>
</Card>
```
## Examples with Icons and Buttons
```
import { Settings, User, Bell, Plus, ChevronRight } from 'lucide-react';
<Card>
<CardHeader>
<div className="flex items-center gap-2">
<User className="size-5 text-text-secondary" />
<CardTitle>User Profile</CardTitle>
</div>
<CardAction>
<Button variant="ghost" size="sm">
<Settings className="size-4" />
</Button>
</CardAction>
</CardHeader>
<CardContent>
<CardDescription className="py-lg">
Manage your account settings and preferences
</CardDescription>
</CardContent>
<CardFooter>
<Button variant="secondary" className="flex-1">
<ChevronRight className="size-4 ml-auto" />
View Details
</Button>
</CardFooter>
</Card>
<Card size="sm">
<CardHeader>
<div className="flex items-center gap-2">
<Bell className="size-4 text-text-secondary" />
<CardTitle>Notifications</CardTitle>
</div>
</CardHeader>
<CardContent>
<CardDescription className="py-lg">3 new updates available</CardDescription>
</CardContent>
<CardFooter>
<Button size="sm" className="w-full">
<Plus className="size-4 mr-2" />
View All
</Button>
</CardFooter>
</Card>
```

View File

@@ -0,0 +1,62 @@
- Home
- Components
- Checkbox
# Checkbox
A control that allows the user to toggle between checked and not checked.
## Props
Prop Type Default Description
checkall boolean false Renders a square fill style for "select all" semantics
...Radix props ComponentProps<typeof CheckboxPrimitive.Root> - All Radix checkbox props
## Types
```
interface CheckboxProps extends ComponentProps<typeof CheckboxPrimitive.Root> {
checkall?: boolean;
className?: string;
}
```
## Usage
```
<div className="flex flex-col gap-6">
<div className="flex items-center gap-3">
<Checkbox id="Checkbox" />
<label htmlFor="Checkbox">Checkbox</label>
</div>
<div className="flex items-center gap-3">
<Checkbox id="Checkbox disabled" disabled />
<label htmlFor="Checkbox disabled">Checkbox disabled</label>
</div>
<div className="flex items-center gap-3">
<Checkbox id="Checkbox disabled checked" disabled defaultChecked />
<label htmlFor="Checkbox disabled checked">Checkbox disabled checked</label>
</div>
<div className="flex items-center gap-3">
<Checkbox id="checkall" checkall />
<label htmlFor="checkall">Check all</label>
</div>
<div className="flex items-center gap-3">
<Checkbox id="Check all disabled" checkall disabled />
<label htmlFor="Check all disabled">Check all disabled</label>
</div>
<div className="flex items-center gap-3">
<Checkbox id="Check all disabled checked" defaultChecked disabled checkall />
<label htmlFor="Check all disabled checked">Check all disabled checked</label>
</div>
</div>
```
### Examples
```
<Checkbox id="opt-in" />
<Checkbox id="select-all" checkall />
```

View File

@@ -0,0 +1,58 @@
- Home
- Components
- Collapsible
# Collapsible
An interactive component which expands/collapses a panel.
## Props
All parts mirror Radix Collapsible props:
- Collapsible: root container
- CollapsibleTrigger: toggles state (supports asChild)
- CollapsibleContent: animated content area
### Example
```
<Collapsible>
<CollapsibleTrigger asChild>
<Button variant="ghost">Toggle</Button>
</CollapsibleTrigger>
<CollapsibleContent>Hidden content</CollapsibleContent>
</Collapsible>
```
## Usage
#### @peduarte starred 3 repositories
```
<Collapsible className="flex w-[350px] flex-col gap-2">
<div className="flex items-center justify-between gap-4 px-4">
<h4 className="text-sm font-semibold">
@peduarte starred 3 repositories
</h4>
<CollapsibleTrigger asChild>
<Button title="This is a collapsible trigger" variant="ghost" size="icon" className="size-8">
<ChevronsUpDown/>
<span className="sr-only">Toggle</span>
</Button>
</CollapsibleTrigger>
</div>
<div className="rounded-md px-4 py-2 text-sm hover:bg-bg-secondary">
@radix-ui/primitives
</div>
<CollapsibleContent className="flex flex-col gap-2">
<div className="rounded-md px-4 py-2 text-sm hover:bg-bg-secondary">
@radix-ui/colors
</div>
<div className="rounded-md px-4 py-2 text-sm hover:bg-bg-secondary">
@stitches/react
</div>
</CollapsibleContent>
</Collapsible>
```

View File

@@ -0,0 +1,59 @@
- Home
- Components
- Cursor Display
# Cursor Display
Built-in components with Cursor highlighting
## CursorButton
```
<div className="flex flex-col gap-2">
<div className="space-x-2">
<CursorButton>CursorButton</CursorButton>
<CursorButton variant="secondary">CursorButton</CursorButton>
<CursorButton variant="destructive">CursorButton</CursorButton>
<CursorButton variant="ghost">CursorButton</CursorButton>
</div>
<div className="space-x-2">
<Button>Button</Button>
<Button variant="secondary">Button</Button>
<Button variant="destructive">Button</Button>
<Button variant="ghost">Button</Button>
</div>
</div>
```
## CursorInputRoot
```
<CursorInputRoot size="sm" placeholder="CursorInputRoot" / >
<CursorInputRoot size="sm" placeholder="CursorInputRoot" state="error"/ >
<CursorInputRoot size="sm" placeholder="CursorInputRoot" disabled/>
```
## CursorSelectTrigger
```
<CursorSelectTrigger size="sm" className="w-[120px]">
<SelectValue placeholder="CursorSelectTrigger"/>
</CursorSelectTrigger>
<CursorSelectTrigger disabled size="sm" className="w-[120px]">
<SelectValue placeholder="CursorSelectTrigger"/>
</CursorSelectTrigger>
<CursorSelectTrigger state="error" size="sm" className="w-[120px]">
<SelectValue placeholder="CursorSelectTrigger"/>
</CursorSelectTrigger>
```
## CursorTextarea
```
<CursorTextarea size="base" placeholder="Type your message here." />
<CursorTextarea disabled placeholder="Type your message here." />
<CursorTextarea state="error" placeholder="Type your message here." />
```

View File

@@ -0,0 +1,82 @@
- Home
- Components
- Drag Selectable
# Drag Selectable
A React component system that enables drag selection over a vertical list of items with toggle-based multi-select behavior.
## Live Example
Try the drag selection below:
- Normal drag: Toggle selection
- Ctrl/Cmd + drag: Replace selection
- Escape: Clear all selections
```
import React from 'react';
import { Card, Badge, useDragSelect } from '@vuer-ai/vuer-uikit';
const TODOS = [
{ key: "1", title: "Learn React hooks" },
{ key: "2", title: "Build a todo app" },
{ key: "3", title: "Implement drag selection" },
// ... more items
];
export default function DragSelectExample() {
const { selectedItems, getItemProps, clearSelection } = useDragSelect();
return (
<div>
<button onClick={clearSelection}>
Clear ({selectedItems.size} selected)
</button>
{TODOS.map(todo => (
<TodoItem
key={todo.key}
title={todo.title}
checked={selectedItems.has(todo.key)}
{...getItemProps(todo.key)}
/>
))}
</div>
);
}
```
## Simple API
The useDragSelect() hook provides everything you need for drag selection:
Returns:
- selectedItems: Set<string> - Currently selected item IDs
- getItemProps(id: string) - Props to spread on selectable items
- clearSelection() - Function to clear all selections
- isSelected(id: string) - Check if item is selected
Usage: Just import the hook, call it, and spread getItemProps(id) on your items. The hook handles all the complex state management, event handling, and keyboard shortcuts automatically.
## Features
- Automatic Event Handling - Mouse and keyboard events handled internally
- Modifier Key Support - Ctrl/Cmd for replace mode, default toggle mode
- Global Events - Mouse up and Escape key work anywhere on page
- TypeScript Support - Fully typed hook and props
- Zero Dependencies - Pure React implementation
## Selection Modes
- Toggle (default): Items flip their selection state during drag
- Replace (Ctrl/Cmd + drag): Clear existing selection, start new selection range
## Accessibility
- Semantic HTML structure
- Keyboard navigation support
- Screen reader friendly markup
- Clear visual feedback for selection states

81
docs/components/drawer.md Normal file
View File

@@ -0,0 +1,81 @@
- Home
- Components
- Drawer
# Drawer
A drawer component for React.
## Props
### Drawer
Prop Type Default Description
...Vaul props ComponentProps<typeof DrawerPrimitive.Root> - All Vaul drawer root props
### Drawer Root
Prop Type Default Description
direction 'top' | 'right' | 'bottom' | 'left' 'bottom' Which edge to slide from
...Vaul props ComponentProps<typeof DrawerPrimitive.Root> - All Vaul root props
### DrawerContent
Prop Type Default Description
...Vaul props ComponentProps<typeof DrawerPrimitive.Content> - All Vaul content props
Other parts (DrawerTrigger, DrawerPortal, DrawerOverlay, DrawerHeader, DrawerFooter, DrawerTitle, DrawerDescription, DrawerClose) are styled wrappers around Vaul components.
## Usage
```
<Drawer>
<DrawerTrigger asChild>
<Button variant="outline">Open</Button>
</DrawerTrigger>
<DrawerContent onOpenAutoFocus={(e) => {
e.preventDefault();
}}>
<DrawerHeader>
<DrawerTitle>Edit profile</DrawerTitle>
<DrawerDescription>
Make changes to your profile here. Click save when you&apos;re done.
</DrawerDescription>
</DrawerHeader>
<div className="grid flex-1 auto-rows-min gap-4">
<div className="grid gap-3">
<label className="text-[12px]" htmlFor="sheet-demo-name">Name</label>
<InputRoot id="sheet-demo-name" defaultValue="Pedro Duarte" />
</div>
<div className="grid gap-3">
<label className="text-[12px]" htmlFor="sheet-demo-username">Username</label>
<InputRoot id="sheet-demo-username" defaultValue="@peduarte" />
</div>
</div>
<DrawerFooter>
<Button variant="primary">Save</Button>
<SheetClose asChild>
<Button variant="secondary">Close</Button>
</SheetClose>
</DrawerFooter>
</DrawerContent>
</Drawer>
```
### Example
```
<Drawer>
<DrawerTrigger asChild><Button>Open</Button></DrawerTrigger>
<DrawerContent>
<DrawerHeader>
<DrawerTitle>Title</DrawerTitle>
<DrawerDescription>Description</DrawerDescription>
</DrawerHeader>
</DrawerContent>
</Drawer>
```

147
docs/components/dropdown.md Normal file
View File

@@ -0,0 +1,147 @@
- Home
- Components
- Dropdown
# Dropdown Menu
Displays a menu to the user — such as a set of actions or functions — triggered by a button.
## Props
All primitives mirror Radix Dropdown Menu props.
- DropdownMenu: root provider
- DropdownMenuTrigger: trigger element (supports asChild)
- DropdownMenuContent: menu content, accepts align, sideOffset
- DropdownMenuGroup, DropdownMenuLabel, DropdownMenuSeparator
- DropdownMenuItem: accepts inset?: boolean, variant?: 'default' | 'destructive'
- DropdownMenuCheckboxItem: controlled/unchecked states via checked
- DropdownMenuRadioGroup and DropdownMenuRadioItem
- DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent
- DropdownMenuShortcut: right-aligned shortcut text
## Usage
```
<DropdownMenu modal={false}>
<DropdownMenuTrigger asChild>
<Button variant="outline">Dropdown Menu</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56" align="start">
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuGroup>
<DropdownMenuItem>
Profile
<DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
Billing
<DropdownMenuShortcut>⌘B</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
Settings
<DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
Keyboard shortcuts
<DropdownMenuShortcut>⌘K</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>Team</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>Invite users</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuItem>Email</DropdownMenuItem>
<DropdownMenuItem>Message</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>More...</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
<DropdownMenuItem>
New Team
<DropdownMenuShortcut>⌘+T</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem className="mb-xs">GitHub</DropdownMenuItem>
<DropdownMenuItem className="mb-xs">Support</DropdownMenuItem>
<DropdownMenuItem disabled>API</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>
Log out
<DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
```
## Checkboxes
```
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">Open</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56">
<DropdownMenuLabel>Appearance</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuCheckboxItem
checked={true}
>
Status Bar
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem
checked={true}
disabled
>
Activity Bar
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem
checked={false}
>
Panel
</DropdownMenuCheckboxItem>
</DropdownMenuContent>
</DropdownMenu>
```
## Radio Group
```
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">Open</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56">
<DropdownMenuLabel>Panel Position</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuRadioGroup value={"top"}>
<DropdownMenuRadioItem value="top">Top</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="right">Right</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuContent>
</DropdownMenu>
```
### Example
```
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">Open</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<DropdownMenuLabel>Actions</DropdownMenuLabel>
<DropdownMenuItem inset>New File</DropdownMenuItem>
<DropdownMenuItem variant="destructive">Delete</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuCheckboxItem checked>Show Hidden</DropdownMenuCheckboxItem>
</DropdownMenuContent>
</DropdownMenu>
```

70
docs/components/layout.md Normal file
View File

@@ -0,0 +1,70 @@
- Home
- Components
- Layout
#FormLayout
A layout component for organizing content with flexible orientation and alignment options.
## Props
Prop Type Default Description
orientation 'horizontal' | 'vertical' 'horizontal' Layout direction
align 'start' | 'center' | 'end' 'start' Cross-axis alignment
asChild boolean false Render with Slot to style a child element
...div props ComponentProps<'div'> - All native div props
### Examples
```
<FormLayout asChild orientation="label-left" align="end">
<label>
<span>Email</span>
<InputRoot type="email" placeholder="you@example.com" />
</label>
</FormLayout>
```
## Usage
Number
```
<FormLayout asChild className="w-2xs">
<label className="text-uk-md">
<p>Number</p>
<InputRoot placeholder="input"/>
</label>
</FormLayout>
```
## vertical
Number
```
<FormLayout asChild className="w-2xs" orientation="label-left">
<label>
<p className="text-uk-md">Number</p>
<InputRoot placeholder="input"/>
</label>
</FormLayout>
```
## vertical start
Number
```
<FormLayout asChild className="w-2xs">
<label>
<p className="text-uk-md">Number</p>
<InputRoot placeholder="input"/>
</label>
</FormLayout>
```

88
docs/components/modal.md Normal file
View File

@@ -0,0 +1,88 @@
- Home
- Components
- Modal
# Modal
A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.
## Props
### Modal
Prop Type Default Description
...Radix props ComponentProps<typeof DialogPrimitive.Root> - All Radix Dialog root props
### ModalContent
Prop Type Default Description
showCloseButton boolean true Whether to render the built-in close button
...Radix props ComponentProps<typeof DialogPrimitive.Content> - All Radix content props
Other parts (ModalTrigger, ModalOverlay, ModalPortal, ModalHeader, ModalTitle, ModalDescription, ModalFooter, ModalClose) are thin wrappers over corresponding Radix components with styling.
### Example
```
<Modal>
<ModalTrigger asChild>
<Button>Open</Button>
</ModalTrigger>
<ModalContent showCloseButton>
<ModalHeader>
<ModalTitle>Title</ModalTitle>
<ModalDescription>Description</ModalDescription>
</ModalHeader>
<ModalFooter>
<ModalClose asChild><Button variant="secondary">Close</Button></ModalClose>
<Button>Confirm</Button>
</ModalFooter>
</ModalContent>
</Modal>
```
## Usage
```
<Modal>
<ModalTrigger asChild>
<Button variant="primary">Open Modal</Button>
</ModalTrigger>
<ModalContent onOpenAutoFocus={(e) => {
e.preventDefault();
}}>
<ModalHeader>
<ModalTitle>Edit Profile</ModalTitle>
<ModalDescription>Update your personal information. Click Save to complete the changes.</ModalDescription>
</ModalHeader>
<div className="grid gap-4 py-4">
<div className="grid grid-cols-6 items-center gap-2">
<label htmlFor="name" className="text-left text-sm font-medium">Name</label>
<InputRoot
id="name"
defaultValue="Jason"
className="col-span-5 px-3 py-2"
/>
</div>
<div className="grid grid-cols-6 items-center gap-2">
<label htmlFor="name" className="text-left text-sm font-medium">Mail</label>
<InputRoot
id="email"
defaultValue="jason@example.com"
className="col-span-5 px-3 py-2"
/>
</div>
</div>
<ModalFooter>
<ModalClose asChild>
<Button variant="secondary">cancel</Button>
</ModalClose>
<Button>save</Button>
</ModalFooter>
</ModalContent>
</Modal>
```

164
docs/components/navbar.md Normal file
View File

@@ -0,0 +1,164 @@
- Home
- Components
- Navbar
# Navbar
The Navbar component provides a consistent navigation experience across your application. It includes built-in support for search, theme switching, and mobile responsiveness.
## Props
Prop Type Default Description
title string - The title/logo text to display
onSearch (query: string) => void - Callback function for search
showThemeToggle boolean false Whether to show the theme toggle
currentTheme 'light' | 'dark' | 'auto' - Current theme state
onThemeChange (theme: string) => void - Callback for theme changes
## Overview
The Navbar is a top-level navigation component that typically contains the application logo, navigation links, search functionality, and user controls like theme switching.
## Features
- Responsive Design: Automatically adapts to mobile and desktop
- Theme Switching: Built-in light/dark mode toggle
- Search Integration: Optional search functionality
- Customizable: Easy to customize with props
## Basic Usage
```
import { Navbar } from '@vuer-ai/vuer-uikit';
function App() {
return (
<Navbar title="My Application" />
);
}
```
## With Search
```
import { Navbar } from '@vuer-ai/vuer-uikit';
function App() {
const handleSearch = (query) => {
console.log('Search query:', query);
};
return (
<Navbar
title="My Application"
onSearch={handleSearch}
/>
);
}
```
## With Theme Toggle
```
import { Navbar } from '@vuer-ai/vuer-uikit';
function App() {
return (
<Navbar
title="My Application"
showThemeToggle={true}
/>
);
}
```
## API Reference
### Examples
#### Basic Navbar
```
<Navbar title="My App" />
```
#### Navbar with Search
```
<Navbar
title="My App"
onSearch={(query) => {
// Handle search
console.log('Searching for:', query);
}}
/>
```
#### Navbar with Theme Toggle
```
<Navbar
title="My App"
showThemeToggle={true}
currentTheme="light"
onThemeChange={(theme) => {
// Handle theme change
console.log('Theme changed to:', theme);
}}
/>
```
## Mobile Behavior
On mobile devices, the navbar automatically adapts:
- Search bar collapses into a mobile-friendly interface
- Theme toggle remains accessible
- Touch targets are appropriately sized
- Responsive breakpoints ensure good UX
## Customization
### Styling
You can customize the navbar appearance using CSS custom properties:
```
.vuer-navbar {
--navbar-bg: var(--neutral-50);
--navbar-border: var(--neutral-200);
--navbar-height: 4rem;
--navbar-padding: 1rem;
}
```
### Custom Content
For more complex navigation needs, you can extend the navbar with custom content:
```
<Navbar title="My App">
<div className="custom-nav-content">
<a href="/dashboard">Dashboard</a>
<a href="/profile">Profile</a>
</div>
</Navbar>
```
## Accessibility
- Proper semantic HTML structure
- Keyboard navigation support
- Screen reader announcements
- Focus management
- ARIA labels and descriptions
## Best Practices
- Keep the title concise and recognizable
- Provide meaningful search functionality
- Use theme toggle for better user experience
- Ensure mobile responsiveness
- Test with keyboard navigation

View File

@@ -0,0 +1,54 @@
- Home
- Components
- Navigation
# Navigation
A navigation component with back/forward buttons and title display.
## Props
Prop Type Default Description
title string - The title text to display
onBack () => void - Callback for back button click
onForward () => void - Callback for forward button click
canGoBack boolean true Whether the back button should be enabled
canGoForward boolean true Whether the forward button should be enabled
size "sm" | "md" | "lg" "md" Size variant for buttons and title
className string - Additional CSS class names
## Basic Usage
```
<Navigation
title="Community"
/>
```
## Sizes
```
<Navigation size="sm" title="Small Navigation" />
<Navigation size="md" title="Medium Navigation" />
<Navigation size="lg" title="Large Navigation" />
```
## Disabled States
```
<Navigation
title="Cannot Go Back"
canGoBack={false}
/>
<Navigation
title="Cannot Go Forward"
canGoForward={false}
/>
<Navigation
title="Both Disabled"
canGoBack={false}
canGoForward={false}
/>
```

View File

@@ -0,0 +1,44 @@
- Home
- Components
- Pagination
## Pagination
Pagination with page navigation, next and previous links.
## Usage
- Previous
- 1
- 2
- 3
- More pages
- Next
```
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="#" />
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">1</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#" isActive>
2
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">3</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
<PaginationItem>
<PaginationNext href="#" />
</PaginationItem>
</PaginationContent>
</Pagination>
```

View File

@@ -0,0 +1,95 @@
- Home
- Components
- Popover
# Popover
Displays rich content in a portal, triggered by a button.
## Props
### Popover
Prop Type Default Description
...Radix props ComponentProps<typeof PopoverPrimitive.Root> - All Radix Popover root props
### PopoverContent
Prop Type Default Description
align 'start' | 'center' | 'end' 'center' Content alignment relative to trigger
sideOffset number 4 Offset in pixels from the trigger
...Radix props ComponentProps<typeof PopoverPrimitive.Content> - All Radix content props
## Usage
```
<Popover>
<PopoverTrigger asChild>
<Button variant="outline">Open popover</Button>
</PopoverTrigger>
<PopoverContent className="w-80" align="start" onOpenAutoFocus={(e) => {
e.preventDefault();
}}>
<div>
<div className="space-y-2 mb-2">
<h4 className="leading-none font-medium">Dimensions</h4>
<p className="text-muted-foreground text-sm">
Set the dimensions for the layer.
</p>
</div>
<div className="space-y-2">
<FormLayout asChild className="w-2xs" orientation="label-left">
<label>
<p className="text-uk-md text-left">Width</p>
<InputRoot
id="width"
defaultValue="300px"
/>
</label>
</FormLayout>
<FormLayout asChild className="w-2xs" orientation="label-left">
<label>
<p className="text-uk-md text-left">Max width</p>
<InputRoot
id="maxWidth"
defaultValue="300px"
/>
</label>
</FormLayout>
<FormLayout asChild className="w-2xs" orientation="label-left">
<label>
<p className="text-uk-md text-left">Height</p>
<InputRoot
id="height"
defaultValue="300px"
/>
</label>
</FormLayout>
<FormLayout asChild className="w-2xs" orientation="label-left">
<label>
<p className="text-uk-md text-left">Max height</p>
<InputRoot
id="maxHeight"
defaultValue="300px"
/>
</label>
</FormLayout>
</div>
</div>
</PopoverContent>
</Popover>
```
### Example
```
<Popover>
<PopoverTrigger asChild>
<Button variant="outline">Open</Button>
</PopoverTrigger>
<PopoverContent align="start" sideOffset={8}>Content</PopoverContent>
</Popover>
```

View File

@@ -0,0 +1,97 @@
- Home
- Components
- Preview
# Preview
The Preview component is used throughout the documentation to display components alongside their code examples. It supports flexible layouts for showcasing components in different arrangements.
## FormLayout Options
## Default Layout
By default, the Preview component displays components horizontally with code below:
```
<Button>Default Layout</Button>
```
### Left Layout
Use left prop to position the component on the left side with a fixed width:
```
<Button>Left Layout</Button>
```
### Right Layout
Use right prop to position the component on the right side with a fixed width:
```
<Button>Right Layout</Button>
```
### Custom Width
You can specify custom widths for left or right layouts:
```
<Button>Custom Width (300px)</Button>
```
```
<Button>Custom Width (150px)</Button>
```
## Props
### Required Props
Prop Type Description
children ReactNode Required. The code example content to display. Typically contains a markdown code block with syntax highlighting.
component ReactNode Required. The actual component or JSX element to render in the preview panel.
### Layout Props
Prop Type Default Description
left boolean | number undefined Positions the component on the left side with code on the right. If true, uses default width of 200px. If a number, uses that value as width in pixels.
right boolean | number undefined Positions the component on the right side with code on the left. If true, uses default width of 200px. If a number, uses that value as width in pixels.
### Code Block Props
Prop Type Default Description
lines number undefined Fixed height in lines. If collapsed=true, shows this many lines when collapsed. If collapsed=false, uses this as max height with scroll.
collapsed boolean false Enable collapse/expand button functionality.
startCollapsed boolean false Start in collapsed state (requires collapsed=true).
maxLines number undefined When expanded, max lines before adding scroll. Only works with collapsed=true.
### Default Values
The Preview component uses these constants for default widths:
- Default left width: 200px (when left={true})
- Default right width: 200px (when right={true})
### Layout Behavior
- Default layout (no left or right prop): Component displays above the code block in a horizontal stack
- Left layout (left prop): Component panel on left (fixed width), code panel on right (flexible width)
- Right layout (right prop): Code panel on left (flexible width), component panel on right (fixed width)
- Mutual exclusivity: Only use either left OR right, never both simultaneously
## Usage Notes
- Only use either left OR right prop, not both
- When no layout prop is provided, uses the default horizontal layout
- The Preview component handles responsive behavior and code block styling automatically
- Default widths are 200px for both left and right layouts
- Code blocks automatically include copy buttons
- Use collapsed={true} to enable collapse/expand functionality
- Use lines={n} for fixed height or collapsed display height
- Use maxLines={n} with collapsed={true} to control expanded height
- Use startCollapsed={true} to begin in collapsed state

View File

@@ -0,0 +1,65 @@
- Home
- Components
- Progress
# Progress
Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.
## Props
Prop Type Default Description
value number 0 The progress value (0-100)
max number 100 The maximum value
className string - Additional CSS classes
...progress props ComponentProps<typeof ProgressPrimitive.Root> - All Radix Progress props are supported
## Basic Usage
```
<div className="w-60 space-y-6">
<div className="flex flex-col gap-1 items-end">
<span className="text-uk-md text-text-secondary">0%</span>
<Progress value={0} />
</div>
<div className="flex flex-col gap-1 items-end">
<span className="text-uk-md text-text-secondary">50%</span>
<Progress value={50} />
</div>
<div className="flex flex-col gap-1 items-end">
<span className="text-uk-md text-text-secondary">100%</span>
<Progress value={100} />
</div>
</div>
```
## Animated Progress
```
function AnimatedProgress() {
const [progress, setProgress] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setProgress((prev) => {
if (prev >= 100) return 0;
return prev + 10;
});
}, 500);
return () => clearInterval(timer);
}, []);
return (
<div className="w-60 space-y-4">
<div className="flex justify-between">
<span className="text-sm font-medium">Animated Progress</span>
<span className="text-sm text-muted-foreground">{progress}%</span>
</div>
<Progress value={progress} />
</div>
);
}
```

View File

@@ -0,0 +1,61 @@
- Home
- Components
- Radio Group
# RadioGroup
A set of checkable buttons—known as radio buttons—where no more than one of the buttons can be checked at a time.
## Props
Component Notes
RadioGroup Pass-through wrapper over Radix RadioGroup.Root with layout classes
RadioGroupItem Pass-through wrapper over Radix RadioGroup.Item with styles
All Radix props are supported.
### Example
```
<RadioGroup defaultValue="a">
<div className="flex items-center gap-3">
<RadioGroupItem value="a" id="a" />
<label htmlFor="a">Option A</label>
</div>
</RadioGroup>
```
## Usage
```
<RadioGroup defaultValue="r2">
<div className="flex items-center gap-3">
<RadioGroupItem value="r1" id="r1" />
<label htmlFor="r1">Radio 1</label>
</div>
<div className="flex items-center gap-3">
<RadioGroupItem value="r2" id="r2" />
<label htmlFor="r2">Radio 2</label>
</div>
<div className="flex items-center gap-3">
<RadioGroupItem value="r3" id="r3" disabled />
<label htmlFor="r3">Radio 3 disabled</label>
</div>
</RadioGroup>
<RadioGroup defaultValue="r3">
<div className="flex items-center gap-3">
<RadioGroupItem value="r1" id="r1" />
<label htmlFor="r1">Radio 1</label>
</div>
<div className="flex items-center gap-3">
<RadioGroupItem value="r2" id="r2" />
<label htmlFor="r2">Radio 2</label>
</div>
<div className="flex items-center gap-3">
<RadioGroupItem value="r3" id="r3" disabled />
<label htmlFor="r3">Radio 3 disabled</label>
</div>
</RadioGroup>
```

241
docs/components/select.md Normal file
View File

@@ -0,0 +1,241 @@
- Home
- Components
- Select
# Select
Displays a list of options for the user to pick from—triggered by a button.
## Types
```
interface SelectTriggerProps extends ComponentProps<typeof SelectPrimitive.Trigger>, VariantProps<typeof selectTriggerVariants> {
state?: "default" | "disabled" | "error";
size?: "sm" | "md" | "lg";
font?: "standard" | "mono";
align?: "left" | "center" | "right";
}
interface SelectItemProps extends ComponentProps<typeof SelectPrimitive.Item> {
prefix?: ReactNode;
suffix?: ReactNode;
}
// Other select components use Radix primitives:
// SelectRoot, SelectGroup, SelectValue, SelectContent,
// SelectLabel, SelectSeparator - all extend Radix component props
```
## In Toolbar
```
<Toolbar>
<ToolbarGroup>
<Button icon variant="ghost" size="sm">
<Settings className="size-4" />
</Button>
<Select defaultValue="medium">
<SelectTrigger size="sm" className="w-20">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value="small">S</SelectItem>
<SelectItem value="medium">M</SelectItem>
<SelectItem value="large">L</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
<Button icon variant="ghost" size="sm">
<Download className="size-4" />
</Button>
</ToolbarGroup>
</Toolbar>
```
## Props
### Select
Prop Type Default Description
font 'standard' | 'mono' 'mono' Font family applied to trigger and items
align 'left' | 'center' | 'right' 'left' Text alignment applied to trigger and items
...Radix props ComponentProps<typeof SelectPrimitive.Root> - All Radix Select root props
### SelectTrigger
Prop Type Default Description
size 'sm' | 'md' | 'lg' 'md' Trigger size
state 'default' | 'error' 'default' Visual state
...Radix props ComponentProps<typeof SelectPrimitive.Trigger> - All Radix trigger props
### SelectContent
Prop Type Default Description
position 'item-aligned' | 'popper' 'item-aligned' Positioning strategy
...Radix props ComponentProps<typeof SelectPrimitive.Content> - All Radix content props
### SelectItem
Prop Type Default Description
prefix ReactNode - Element rendered before the label
suffix ReactNode - Element rendered after the label
...Radix props ComponentProps<typeof SelectPrimitive.Item> - All Radix item props
### SelectLabel, SelectGroup, SelectSeparator, SelectScrollUpButton, SelectScrollDownButton, SelectValue
Pass-through wrappers for corresponding Radix components.
## Usage
```
<Select defaultValue="apple">
<SelectTrigger size="sm" className="w-[180px]">
<SelectValue placeholder="Select a fruit"/>
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Fruits</SelectLabel>
<SelectItem value="apple">Apple</SelectItem>
<SelectItem value="banana" prefix={<Plus/>}>Banana</SelectItem>
<SelectItem disabled value="blueberry">Blueberry</SelectItem>
<SelectItem value="grapes" suffix={<>Suffix<Minus/></>}>Grapes</SelectItem>
<SelectItem value="pineapple">Pineapple</SelectItem>
</SelectGroup>
<SelectSeparator/>
<SelectGroup>
<SelectLabel>Vegetables</SelectLabel>
<SelectItem value="aubergine">Aubergine</SelectItem>
<SelectItem value="broccoli">Broccoli</SelectItem>
<SelectItem disabled value="carrot">Carrot</SelectItem>
<SelectItem value="courgette">Courgette</SelectItem>
<SelectItem value="leek">Leek</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
```
## State
```
<Select>
<SelectTrigger disabled size="sm" className="w-[180px]">
<SelectValue placeholder="Disabled"/>
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Fruits</SelectLabel>
<SelectItem value="apple">Apple</SelectItem>
<SelectItem value="banana">Banana</SelectItem>
<SelectItem value="blueberry">Blueberry</SelectItem>
<SelectItem value="grapes">Grapes</SelectItem>
<SelectItem value="pineapple">Pineapple</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
```
## Sides
Left
Top
Bottom
Right
```
<p className="text-sm font-medium mb-2">Left</p>
<Select>
<SelectTrigger size="sm" className="w-[120px]">
<SelectValue placeholder="Left"/>
</SelectTrigger>
<SelectContent side="<left | top | bottom | right>" position="popper">
<SelectGroup>
<SelectItem value="left1">Left 1</SelectItem>
<SelectItem value="left2">Left 2</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
```
## Font Styles
Standard Font
Mono Font
```
{/* Standard font */}
<Select font="standard">
<SelectTrigger size="sm" className="w-[120px]">
<SelectValue placeholder="Standard"/>
</SelectTrigger>
</Select>
{/* Monospace font (default) */}
<Select font="mono">
<SelectTrigger size="sm" className="w-[120px]">
<SelectValue placeholder="Mono"/>
</SelectTrigger>
</Select>
```
## Text Alignment
Left Aligned
Center Aligned
Right Aligned
```
{/* Left aligned (default) */}
<Select align="left">
<SelectTrigger size="sm" className="w-[140px]">
<SelectValue placeholder="Left aligned"/>
</SelectTrigger>
</Select>
{/* Center aligned */}
<Select align="center">
<SelectTrigger size="sm" className="w-[140px]">
<SelectValue placeholder="Center aligned"/>
</SelectTrigger>
</Select>
{/* Right aligned */}
<Select align="right">
<SelectTrigger size="sm" className="w-[140px]">
<SelectValue placeholder="Right aligned"/>
</SelectTrigger>
</Select>
```
## Error
```
<Select>
<SelectTrigger state="error" size="sm" className="w-[180px]">
<SelectValue placeholder="Error"/>
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Fruits</SelectLabel>
<SelectItem value="apple">Apple</SelectItem>
<SelectItem value="banana">Banana</SelectItem>
<SelectItem value="blueberry">Blueberry</SelectItem>
<SelectItem value="grapes">Grapes</SelectItem>
<SelectItem value="pineapple">Pineapple</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
```

77
docs/components/sheet.md Normal file
View File

@@ -0,0 +1,77 @@
- Home
- Components
- Sheet
# Sheet
Extends the Dialog component to display content that complements the main content of the screen.
## Props
### Sheet
Prop Type Default Description
...Radix props ComponentProps<typeof SheetPrimitive.Root> - All Radix Dialog root props
### SheetContent
Prop Type Default Description
side 'top' | 'right' | 'bottom' | 'left' 'right' Which edge to slide from
...Radix props ComponentProps<typeof SheetPrimitive.Content> - All Radix content props
Other parts (SheetTrigger, SheetClose, SheetHeader, SheetFooter, SheetTitle, SheetDescription) are styled wrappers around Radix components.
### Example
```
<Sheet>
<SheetTrigger asChild>
<Button>Open</Button>
</SheetTrigger>
<SheetContent side="left">
<SheetHeader>
<SheetTitle>Title</SheetTitle>
<SheetDescription>Optional description</SheetDescription>
</SheetHeader>
</SheetContent>
</Sheet>
```
## Usage
```
<Sheet>
<SheetTrigger asChild>
<Button variant="outline">Open</Button>
</SheetTrigger>
<SheetContent onOpenAutoFocus={(e) => {
e.preventDefault();
}}>
<SheetHeader>
<SheetTitle>Edit profile</SheetTitle>
<SheetDescription>
Make changes to your profile here. Click save when you&apos;re done.
</SheetDescription>
</SheetHeader>
<div className="grid flex-1 auto-rows-min gap-4">
<div className="grid gap-3">
<label className="text-[12px]" htmlFor="sheet-demo-name">Name</label>
<InputRoot id="sheet-demo-name" defaultValue="Pedro Duarte" />
</div>
<div className="grid gap-3">
<label className="text-[12px]" htmlFor="sheet-demo-username">Username</label>
<InputRoot id="sheet-demo-username" defaultValue="@peduarte" />
</div>
</div>
<SheetFooter>
<Button variant="primary">Save</Button>
<SheetClose asChild>
<Button variant="secondary">Close</Button>
</SheetClose>
</SheetFooter>
</SheetContent>
</Sheet>
```

156
docs/components/sidebar.md Normal file
View File

@@ -0,0 +1,156 @@
1. Home
2. Components
3. Sidebar
# Sidebar
A composable, themeable and customizable sidebar component.
## Usage
Ge's Team - Documents
- Team
- Communication
- SidebarMenuAction
- SidebarMenuBadge24
Toggle Sidebar ```jsx
import { ChevronDown, ChevronRight, Folder, FileText, Users, Mail, Bell } from "lucide-react"
import { useState } from "react"
const collapsibleItems = [
{
title: "Documents",
icon: Folder,
items: [
{ title: "Reports", url: "#", icon: FileText },
{ title: "Invoices", url: "#", icon: FileText },
{ title: "Contracts", url: "#", icon: FileText },
],
},
{
title: "Team",
icon: Users,
items: [
{ title: "Members", url: "#", icon: Users },
{ title: "Roles", url: "#", icon: Users },
{ title: "Permissions", url: "#", icon: Users },
],
},
{
title: "Communication",
icon: Mail,
items: [
{ title: "Messages", url: "#", icon: Mail },
{ title: "Notifications", url: "#", icon: Bell },
{ title: "Announcements", url: "#", icon: Bell },
],
},
]
function CollapsibleMenuItem({ item }) {
const [isOpen, setIsOpen] = useState(false)
return (
<>
<SidebarMenuItem>
<SidebarMenuButton onClick={() => setIsOpen(!isOpen)} className="pl-lg">
<item.icon />
<span>{item.title}</span>
{isOpen ? <ChevronDown className="ml-auto" /> : <ChevronRight className="ml-auto" />}
</SidebarMenuButton>
{isOpen && (
<SidebarMenuSub>
{item.items.map((subItem) => (
<SidebarMenuSubItem key={subItem.title}>
<SidebarMenuSubButton asChild>
<a href={subItem.url}>
<subItem.icon />
<span>{subItem.title}</span>
</a>
</SidebarMenuSubButton>
</SidebarMenuSubItem>
))}
</SidebarMenuSub>
)}
</SidebarMenuItem>
<SidebarSeparator />
</>
)
}
<SidebarProvider>
<Sidebar collapsible="offcanvas" className="relative">
<SidebarHeader>
<DropdownMenu className="w-full">
<DropdownMenuTrigger asChild>
<div className="flex items-center gap-md">
<Avatar>
<AvatarImage
src="https://github.com/shadcn.png"
alt="Team Avatar"
/>
<AvatarFallback>GT</AvatarFallback>
</Avatar>
<div className="flex items-center gap-sm">
Ge's Team
<ChevronDown size={16} />
</div>
</div>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-[var(--radix-dropdown-menu-trigger-width)]">
<DropdownMenuItem>
<span>Menu item1</span>
</DropdownMenuItem>
<DropdownMenuItem>
<span>Menu item2</span>
</DropdownMenuItem>
<DropdownMenuItem>
<span>Menu item3</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarInput placeholder="Search for anything" />
<SidebarGroupContent>
<SidebarMenu>
{collapsibleItems.map((item) => (
<CollapsibleMenuItem key={item.title} item={item} />
))}
<SidebarMenuItem>
<SidebarMenuSubButton asChild>
<div>SidebarMenuAction</div>
</SidebarMenuSubButton>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<SidebarMenuAction>
<MoreHorizontal />
</SidebarMenuAction>
</DropdownMenuTrigger>
<DropdownMenuContent side="right" align="start">
<DropdownMenuItem>
<span>Edit Project</span>
</DropdownMenuItem>
<DropdownMenuItem>
<span>Delete Project</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</SidebarMenuItem>
<SidebarMenuItem className="group-data-[collapsible=icon]:hidden">
<SidebarMenuSubButton>
<div>SidebarMenuBadge</div>
</SidebarMenuSubButton>
<SidebarMenuBadge>24</SidebarMenuBadge>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
<SidebarRail />
</Sidebar>
<SidebarTrigger />
</SidebarProvider>
```

View File

@@ -0,0 +1,98 @@
1. Home
2. Components
3. Simple Tree View
# SimpleTreeView
## Types
```typescript
interface TreeDataItem {
id: string;
name: string;
icon?: IconComponent;
selectedIcon?: IconComponent;
openIcon?: IconComponent;
children?: TreeDataItem[];
actions?: ReactNode;
onClick?: () => void;
draggable?: boolean;
droppable?: boolean;
disabled?: boolean;
}
type IconComponent = React.ComponentType<{ className?: string }>;
```
# Simple Tree View
## Props
### SimpleTreeView
| Prop | Type | Description |
| --- | --- | --- |
| data | `TreeDataItem[] | TreeDataItem` |
| initialSelectedItemId | string | Preselect an item and auto-expand ancestors |
| onSelectChange | (item?: TreeDataItem) => void | Callback when selection changes |
| expandAll | boolean | Expand all nodes initially |
| defaultNodeIcon | IconComponent | Default icon for nodes |
| defaultLeafIcon | IconComponent | Default icon for leaves |
| onDocumentDrag | (source: TreeDataItem, target: TreeDataItem) => void | Drag and drop callback |
### TreeDataItem
```ts
type TreeDataItem = {
id: string;
name: string;
icon?: ComponentType<SVGProps<SVGSVGElement>>;
selectedIcon?: ComponentType<SVGProps<SVGSVGElement>>;
openIcon?: ComponentType<SVGProps<SVGSVGElement>>;
children?: TreeDataItem[];
actions?: React.ReactNode;
onClick?: () => void;
draggable?: boolean;
droppable?: boolean;
disabled?: boolean;
}
```
- Item 1
- Item 2
- Item 3
```jsx
const data = [
{ id: '1', name: 'Item 1', icon: ArrowRight,
children: [
{ id: '2', name: 'Item 1.1', icon: AlarmClock,
children: [
{ id: '3', name: 'Item 1.1.1', icon: Ambulance },
{ id: '4', name: 'Item 1.1.2', icon: Angry },
],
},
{ id: '5', name: 'Item 1.2 (disabled)', icon: Album, disabled: true },
],
}, {
id: '6', name: 'Item 2',
children: [
{ id: '7', name: 'Item 2.1', icon: AlignCenterHorizontal },
{ id: '8', name: 'Item 2.2', icon: Blend,
children: [
{ id: '9', name: 'Item 2.2.1', icon: Bird },
{ id: '10', name: 'Item 2.2.2', icon: Biohazard,
children: [
{ id: '11', name: 'Item 2.2.2.1', icon: Cannabis },
{ id: '12', name: 'Item 2.2.2.2 Item 2.2.2.2 Item 2.2.2.2 Item 2.2.2.2 Item 2.2.2.2', icon: Cannabis }
]
},
],
},
],
},
{ id: '13', name: 'Item 3' }
];
<SimpleTreeView data={treeData} className="w-[260px]" />
```

76
docs/components/slider.md Normal file
View File

@@ -0,0 +1,76 @@
1. Home
2. Components
3. Slider
# Slider
An input where the user selects a value from within a given range.
[Docs](https://www.radix-ui.com/primitives/docs/components/slider)[API Reference](https://www.radix-ui.com/primitives/docs/components/slider#api-reference)## Props
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| showStep | boolean | false | Visualize step marks along the track |
| min | number | 0 | Minimum value |
| max | number | 100 | Maximum value |
| step | number | 1 | Step size |
| value | number[] | - | Controlled values for one or more thumbs |
| defaultValue | number[] | - | Uncontrolled initial values |
| onValueChange | (value: number[]) => void | - | Callback when value changes |
| ...Radix props | ComponentProps<typeof SliderPrimitive.Root> | - | All Radix slider props |
## Usage
```jsx
<Slider defaultValue={[50]} max={100} step={0.01}/>
```
### Create a range
```jsx
<Slider defaultValue={[25, 75]} max={100} step={1}/>
```
### Prevent thumb overlap
```jsx
<Slider defaultValue={[20, 70]} max={100} step={10} minStepsBetweenThumbs={1}/>
```
### Define step size
```jsx
<Slider defaultValue={[20]} max={100} step={10}/>
```
### Define step size and show
```jsx
<Slider defaultValue={[20]} min={2} max={100} step={10} showStep/>
```
```jsx
<Slider showStep/>
```
### Examples
```jsx
// Single value
<Slider defaultValue={[50]} min={0} max={100} step={1} />
// Range
<Slider defaultValue={[25, 75]} min={0} max={100} step={1} />
```
### Disabled
```jsx
<Slider defaultValue={[20]} max={100} step={10} disabled/>
```
### Disabled with step
```jsx
<Slider defaultValue={[20]} max={100} step={10} showStep disabled/>
```

View File

@@ -0,0 +1,46 @@
1. Home
2. Components
3. Spinner
# Spinner
The Spinner component provides a visual loading indicator with a smooth ring animation.
It's built using SVG animations for optimal performance and customization.
## Props
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| size | number | 24 | Size of the spinner in pixels |
| className | string | - | Additional CSS classes |
| style | CSSProperties | - | Inline styles |
| ...svg props | SVGProps<SVGSVGElement> | - | All native SVG props are supported |
## Overview
Spinners are used to indicate loading states or ongoing processes. They provide visual feedback to users that the application is working on their request.
## Basic Usage
Loading... Loading... Loading... ```jsx
// Default spinner
<Spinner />
// Medium spinner
<Spinner size={32} />
// Large spinner
<Spinner size={48} />
```
## Custom Styling
Loading... Loading... Loading... Loading... ```jsx
// Custom colors using className
<Spinner className="text-blue-500" />
<Spinner className="text-green-500" size={32} />
<Spinner className="text-red-500" size={48} />
// Custom color using style
<Spinner style={{ color: '#8B5CF6' }} size={32} />
```

42
docs/components/switch.md Normal file
View File

@@ -0,0 +1,42 @@
1. Home
2. Components
3. Switch
# Switch
A control that allows the user to toggle between checked and not checked.
[Docs](https://www.radix-ui.com/primitives/docs/components/switch)[API Reference](https://www.radix-ui.com/primitives/docs/components/switch#api-reference)[shadcn/ui](https://ui.shadcn.com/docs/components/switch)## Props
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| ...Radix props | ComponentProps<typeof SwitchPrimitive.Root> | - | All Radix switch root props |
### Examples
```jsx
<Switch id="notifications" defaultChecked />
```
## Usage
Switch Switch checked Switch disabled Switch disabled checked ```jsx
<div className="flex flex-col gap-6">
<div className="flex items-center gap-2">
<Switch id="Switch" />
<label htmlFor="Switch">Switch</label>
</div>
<div className="flex items-center gap-2">
<Switch id="Switch On" defaultChecked />
<label htmlFor="Switch On">Switch checked</label>
</div>
<div className="flex items-center gap-2">
<Switch id="Switch disabled" disabled />
<label htmlFor="Switch disabled">Switch disabled</label>
</div>
<div className="flex items-center gap-2">
<Switch id="Switch disabled checked" defaultChecked disabled />
<label htmlFor="Switch disabled checked">Switch disabled checked</label>
</div>
</div>
```

View File

@@ -0,0 +1,237 @@
1. Home
2. Components
3. Sync Scroll
# Synchronized Scrolling Components
Components for creating synchronized scrolling experiences with master-slave relationships and drag-to-scroll functionality.
## Basic Usage with Components
Master Scroll Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Item 9 Item 10 Item 11 Item 12 Item 13 Item 14 Item 15 Item 16 Item 17 Item 18 Item 19 Item 20 Item 21 Item 22 Item 23 Item 24 Item 25 Item 26 Item 27 Item 28 Item 29 Item 30 Item 31 Item 32 Item 33 Item 34 Item 35 Item 36 Item 37 Item 38 Item 39 Item 40 Item 41 Item 42 Item 43 Item 44 Item 45 Item 46 Item 47 Item 48 Item 49 Item 50 Slave Scroll Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Item 9 Item 10 Item 11 Item 12 Item 13 Item 14 Item 15 Item 16 Item 17 Item 18 Item 19 Item 20 Item 21 Item 22 Item 23 Item 24 Item 25 Item 26 Item 27 Item 28 Item 29 Item 30 Item 31 Item 32 Item 33 Item 34 Item 35 Item 36 Item 37 Item 38 Item 39 Item 40 Item 41 Item 42 Item 43 Item 44 Item 45 Item 46 Item 47 Item 48 Item 49 Item 50 ```jsx
import {SyncScrollProvider, SyncScroll, SyncScrollSlave} from "@vuer-ai/vuer-uikit";
function App() {
return (
<SyncScrollProvider>
<SyncScroll className="overflow-y-auto h-96">
{/* Master scrollable content */}
</SyncScroll>
<SyncScrollSlave className="overflow-y-auto h-96">
{/* Slave synchronized scroll area */}
</SyncScrollSlave>
</SyncScrollProvider>
);
}
```
## With Drag Control
The drag components now include built-in drag-to-scroll functionality. Click and drag to scroll!
SyncScroll Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Item 9 Item 10 Item 11 Item 12 Item 13 Item 14 Item 15 Item 16 Item 17 Item 18 Item 19 Item 20 Item 21 Item 22 Item 23 Item 24 Item 25 Item 26 Item 27 Item 28 Item 29 Item 30 Item 31 Item 32 Item 33 Item 34 Item 35 Item 36 Item 37 Item 38 Item 39 Item 40 Item 41 Item 42 Item 43 Item 44 Item 45 Item 46 Item 47 Item 48 Item 49 Item 50 SyncDrag 🖱️ Click and drag vertically to scroll all panels Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Item 9 Item 10 Item 11 Item 12 Item 13 Item 14 Item 15 Item 16 Item 17 Item 18 Item 19 Item 20 Item 21 Item 22 Item 23 Item 24 Item 25 Item 26 Item 27 Item 28 Item 29 Item 30 Item 31 Item 32 Item 33 Item 34 Item 35 Item 36 Item 37 Item 38 Item 39 Item 40 Item 41 Item 42 Item 43 Item 44 Item 45 Item 46 Item 47 Item 48 Item 49 Item 50 SyncScrollSlave Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Item 9 Item 10 Item 11 Item 12 Item 13 Item 14 Item 15 Item 16 Item 17 Item 18 Item 19 Item 20 Item 21 Item 22 Item 23 Item 24 Item 25 Item 26 Item 27 Item 28 Item 29 Item 30 Item 31 Item 32 Item 33 Item 34 Item 35 Item 36 Item 37 Item 38 Item 39 Item 40 Item 41 Item 42 Item 43 Item 44 Item 45 Item 46 Item 47 Item 48 Item 49 Item 50 ```jsx
import {SyncScrollProvider, SyncScroll, SyncDrag, SyncScrollSlave} from "@vuer-ai/vuer-uikit";
function App() {
return (
<SyncScrollProvider>
<SyncScroll className="overflow-y-auto h-96">
{/* Master scrollable content */}
</SyncScroll>
<SyncDrag className="overflow-y-auto h-96">
{/* Draggable content with vertical drag-to-scroll */}
</SyncDrag>
<SyncScrollSlave className="overflow-y-auto h-96">
{/* Slave synchronized area */}
</SyncScrollSlave>
</SyncScrollProvider>
);
}
```
## Horizontal Drag Variants
Horizontal drag components allow left/right scrolling via drag gestures:
### Horizontal Draggable Panels - Both Can Be Dragged
Drag either panel to control both - Master (left) overrides Slave (right)
MASTER DRAG (SyncDragX) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 SLAVE DRAG (SyncDragSlaveX) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 ```jsx
import {SyncScrollProvider, SyncDragX, SyncDragSlaveX} from "@vuer-ai/vuer-uikit";
function App() {
return (
<SyncScrollProvider>
<div className="grid grid-cols-2 gap-4">
{/* Master drag - controls all */}
<SyncDragX className="border-2 border-blue-400 rounded h-32 overflow-x-auto bg-blue-50">
<div className="flex gap-4 p-4" style={{width: '1200px'}}>
{/* Horizontal content */}
</div>
</SyncDragX>
{/* Slave drag - follows master but can be dragged */}
<SyncDragSlaveX className="border-2 border-green-400 rounded h-32 bg-green-50">
<div className="flex gap-4 p-4" style={{width: '1200px'}}>
{/* Horizontal content */}
</div>
</SyncDragSlaveX>
</div>
</SyncScrollProvider>
);
}
```
## Omnidirectional Drag Variants
Omnidirectional drag components allow scrolling in any direction via drag gestures:
### Omnidirectional Draggable Panels - Both Can Be Dragged
Drag either panel in any direction - Master (left) overrides Slave (right)
MASTER DRAG (SyncDrag) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 SLAVE DRAG (SyncDragSlave) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ```jsx
import {SyncScrollProvider, SyncDrag, SyncDragSlave} from "@vuer-ai/vuer-uikit";
function App() {
return (
<SyncScrollProvider>
<div className="grid grid-cols-2 gap-4">
{/* Master drag - controls all */}
<SyncDrag className="border-2 border-purple-400 rounded h-64 overflow-auto bg-purple-50">
<div style={{width: '800px', height: '600px'}} className="p-8">
{/* Content that scrolls in both directions */}
</div>
</SyncDrag>
{/* Slave drag - follows master but can be dragged */}
<SyncDragSlave className="border-2 border-orange-400 rounded h-64 bg-orange-50">
<div style={{width: '800px', height: '600px'}} className="p-8">
{/* Content that scrolls in both directions */}
</div>
</SyncDragSlave>
</div>
</SyncScrollProvider>
);
}
```
## Using Hooks Directly
For more control, you can use the hooks directly:
useSyncScroll Hook Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Item 9 Item 10 Item 11 Item 12 Item 13 Item 14 Item 15 Item 16 Item 17 Item 18 Item 19 Item 20 Item 21 Item 22 Item 23 Item 24 Item 25 Item 26 Item 27 Item 28 Item 29 Item 30 Item 31 Item 32 Item 33 Item 34 Item 35 Item 36 Item 37 Item 38 Item 39 Item 40 Item 41 Item 42 Item 43 Item 44 Item 45 Item 46 Item 47 Item 48 Item 49 Item 50 useScrollSlave Hook Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Item 9 Item 10 Item 11 Item 12 Item 13 Item 14 Item 15 Item 16 Item 17 Item 18 Item 19 Item 20 Item 21 Item 22 Item 23 Item 24 Item 25 Item 26 Item 27 Item 28 Item 29 Item 30 Item 31 Item 32 Item 33 Item 34 Item 35 Item 36 Item 37 Item 38 Item 39 Item 40 Item 41 Item 42 Item 43 Item 44 Item 45 Item 46 Item 47 Item 48 Item 49 Item 50 useSyncDrag Hook Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Item 9 Item 10 Item 11 Item 12 Item 13 Item 14 Item 15 Item 16 Item 17 Item 18 Item 19 Item 20 Item 21 Item 22 Item 23 Item 24 Item 25 Item 26 Item 27 Item 28 Item 29 Item 30 Item 31 Item 32 Item 33 Item 34 Item 35 Item 36 Item 37 Item 38 Item 39 Item 40 Item 41 Item 42 Item 43 Item 44 Item 45 Item 46 Item 47 Item 48 Item 49 Item 50 ```jsx
import {SyncScrollProvider, useSyncScroll, useScrollSlave, useSyncDrag} from "@vuer-ai/vuer-uikit";
// Master panel - controls all other panels
function MasterPanel() {
const ref = useSyncScroll();
return (
<div ref={ref} className="overflow-y-auto h-96">
{/* Your scrollable content */}
</div>
);
}
// Slave panel - controlled by master, syncs with other slaves
function SlavePanel() {
const ref = useScrollSlave();
return (
<div ref={ref} className="overflow-y-auto h-96">
{/* Your scrollable content */}
</div>
);
}
// Drag panel - acts like master when dragged
function DragPanel() {
const ref = useSyncDrag();
return (
<div ref={ref} className="overflow-y-auto h-96">
{/* Your draggable content */}
</div>
);
}
function App() {
return (
<SyncScrollProvider>
<MasterPanel/>
<SlavePanel/>
<DragPanel/>
</SyncScrollProvider>
);
}
```
## API Reference
### Components
#### <SyncScrollProvider>
Wraps components that need synchronized scrolling.
#### <SyncScroll>
A scrollable container that synchronizes with other scroll components. Acts as a master that controls all other synchronized elements.
Props: Extends HTMLAttributes<HTMLDivElement>
#### <SyncScrollSlave>
A scrollable container that is controlled by masters and syncs with other slaves.
Props: Extends HTMLAttributes<HTMLDivElement>
#### <SyncDrag>
A draggable container that supports both horizontal and vertical drag-to-scroll. Click and drag in any direction to scroll both horizontally and vertically. Controls synchronized scrolling.
Props: Extends HTMLAttributes<HTMLDivElement>
#### <SyncDragX>
A draggable container that only supports horizontal drag-to-scroll. Click and drag left/right to scroll horizontally only (vertical dragging is disabled). Controls synchronized scrolling.
Props: Extends HTMLAttributes<HTMLDivElement>
### Hooks
#### useSyncScroll()
Returns a ref for a master scroll element that controls all other elements.
#### useScrollSlave()
Returns a ref for a slave scroll element that is controlled by masters and syncs with other slaves.
#### useSyncDrag()
Returns a ref for drag-controlled scrolling that acts like a master in synchronized scrolling.
### Behavior Notes
- Master elements (SyncScroll, useSyncScroll): Control all other synchronized elements
- Slave elements (SyncScrollSlave, useScrollSlave): Are controlled by masters and sync with other slaves
- Drag elements (SyncDrag, SyncDragX, Drag, useSyncDrag): Act like masters with built-in drag-to-scroll functionality
- SyncDrag: Vertical drag-to-scroll
- SyncDragX: Horizontal drag-to-scroll
- Drag: Omnidirectional drag-to-scroll
📍 SyncScroll: Master scroll control - scrolling affects all synchronized elements
📍 SyncScrollSlave: Controlled by masters, syncs with other slaves
📍 SyncDrag: Vertical drag-to-scroll that controls all synchronized elements
📍 SyncDragX: Horizontal drag-to-scroll that controls all synchronized elements
📍 Drag: Omnidirectional drag-to-scroll that controls all synchronized elements

82
docs/components/table.md Normal file
View File

@@ -0,0 +1,82 @@
1. Home
2. Components
3. Drag Selectable
# Drag Selectable
A React component system that enables drag selection over a vertical list of items with toggle-based multi-select behavior.
## Live Example
Try the drag selection below:
- Normal drag: Toggle selection
- Ctrl/Cmd + drag: Replace selection
- Escape: Clear all selections
0 item s selected Clear All Learn React hooks Build a todo app Implement drag selection Style with Tailwind CSS Add dark mode support Write unit tests Deploy to production Add keyboard shortcuts Improve accessibility Add animations ```tsx
import React from 'react';
import { Card, Badge, useDragSelect } from '@vuer-ai/vuer-uikit';
const TODOS = [
{ key: "1", title: "Learn React hooks" },
{ key: "2", title: "Build a todo app" },
{ key: "3", title: "Implement drag selection" },
// ... more items
];
export default function DragSelectExample() {
const { selectedItems, getItemProps, clearSelection } = useDragSelect();
return (
<div>
<button onClick={clearSelection}>
Clear ({selectedItems.size} selected)
</button>
{TODOS.map(todo => (
<TodoItem
key={todo.key}
title={todo.title}
checked={selectedItems.has(todo.key)}
{...getItemProps(todo.key)}
/>
))}
</div>
);
}
```
## Simple API
The useDragSelect() hook provides everything you need for drag selection:
Returns:
- selectedItems: Set<string> - Currently selected item IDs
- getItemProps(id: string) - Props to spread on selectable items
- clearSelection() - Function to clear all selections
- isSelected(id: string) - Check if item is selected
Usage:
Just import the hook, call it, and spread getItemProps(id) on your items. The hook handles all the complex state management, event handling, and keyboard shortcuts automatically.
## Features
- Automatic Event Handling - Mouse and keyboard events handled internally
- Modifier Key Support - Ctrl/Cmd for replace mode, default toggle mode
- Global Events - Mouse up and Escape key work anywhere on page
- TypeScript Support - Fully typed hook and props
- Zero Dependencies - Pure React implementation
## Selection Modes
- Toggle (default): Items flip their selection state during drag
- Replace (Ctrl/Cmd + drag): Clear existing selection, start new selection range
## Accessibility
- Semantic HTML structure
- Keyboard navigation support
- Screen reader friendly markup
- Clear visual feedback for selection states

82
docs/components/tabs.md Normal file
View File

@@ -0,0 +1,82 @@
1. Home
2. Components
3. Drag Selectable
# Drag Selectable
A React component system that enables drag selection over a vertical list of items with toggle-based multi-select behavior.
## Live Example
Try the drag selection below:
- Normal drag: Toggle selection
- Ctrl/Cmd + drag: Replace selection
- Escape: Clear all selections
0 item s selected Clear All Learn React hooks Build a todo app Implement drag selection Style with Tailwind CSS Add dark mode support Write unit tests Deploy to production Add keyboard shortcuts Improve accessibility Add animations ```tsx
import React from 'react';
import { Card, Badge, useDragSelect } from '@vuer-ai/vuer-uikit';
const TODOS = [
{ key: "1", title: "Learn React hooks" },
{ key: "2", title: "Build a todo app" },
{ key: "3", title: "Implement drag selection" },
// ... more items
];
export default function DragSelectExample() {
const { selectedItems, getItemProps, clearSelection } = useDragSelect();
return (
<div>
<button onClick={clearSelection}>
Clear ({selectedItems.size} selected)
</button>
{TODOS.map(todo => (
<TodoItem
key={todo.key}
title={todo.title}
checked={selectedItems.has(todo.key)}
{...getItemProps(todo.key)}
/>
))}
</div>
);
}
```
## Simple API
The useDragSelect() hook provides everything you need for drag selection:
Returns:
- selectedItems: Set<string> - Currently selected item IDs
- getItemProps(id: string) - Props to spread on selectable items
- clearSelection() - Function to clear all selections
- isSelected(id: string) - Check if item is selected
Usage:
Just import the hook, call it, and spread getItemProps(id) on your items. The hook handles all the complex state management, event handling, and keyboard shortcuts automatically.
## Features
- Automatic Event Handling - Mouse and keyboard events handled internally
- Modifier Key Support - Ctrl/Cmd for replace mode, default toggle mode
- Global Events - Mouse up and Escape key work anywhere on page
- TypeScript Support - Fully typed hook and props
- Zero Dependencies - Pure React implementation
## Selection Modes
- Toggle (default): Items flip their selection state during drag
- Replace (Ctrl/Cmd + drag): Clear existing selection, start new selection range
## Accessibility
- Semantic HTML structure
- Keyboard navigation support
- Screen reader friendly markup
- Clear visual feedback for selection states

View File

@@ -0,0 +1,82 @@
1. Home
2. Components
3. Drag Selectable
# Drag Selectable
A React component system that enables drag selection over a vertical list of items with toggle-based multi-select behavior.
## Live Example
Try the drag selection below:
- Normal drag: Toggle selection
- Ctrl/Cmd + drag: Replace selection
- Escape: Clear all selections
0 item s selected Clear All Learn React hooks Build a todo app Implement drag selection Style with Tailwind CSS Add dark mode support Write unit tests Deploy to production Add keyboard shortcuts Improve accessibility Add animations ```tsx
import React from 'react';
import { Card, Badge, useDragSelect } from '@vuer-ai/vuer-uikit';
const TODOS = [
{ key: "1", title: "Learn React hooks" },
{ key: "2", title: "Build a todo app" },
{ key: "3", title: "Implement drag selection" },
// ... more items
];
export default function DragSelectExample() {
const { selectedItems, getItemProps, clearSelection } = useDragSelect();
return (
<div>
<button onClick={clearSelection}>
Clear ({selectedItems.size} selected)
</button>
{TODOS.map(todo => (
<TodoItem
key={todo.key}
title={todo.title}
checked={selectedItems.has(todo.key)}
{...getItemProps(todo.key)}
/>
))}
</div>
);
}
```
## Simple API
The useDragSelect() hook provides everything you need for drag selection:
Returns:
- selectedItems: Set<string> - Currently selected item IDs
- getItemProps(id: string) - Props to spread on selectable items
- clearSelection() - Function to clear all selections
- isSelected(id: string) - Check if item is selected
Usage:
Just import the hook, call it, and spread getItemProps(id) on your items. The hook handles all the complex state management, event handling, and keyboard shortcuts automatically.
## Features
- Automatic Event Handling - Mouse and keyboard events handled internally
- Modifier Key Support - Ctrl/Cmd for replace mode, default toggle mode
- Global Events - Mouse up and Escape key work anywhere on page
- TypeScript Support - Fully typed hook and props
- Zero Dependencies - Pure React implementation
## Selection Modes
- Toggle (default): Items flip their selection state during drag
- Replace (Ctrl/Cmd + drag): Clear existing selection, start new selection range
## Accessibility
- Semantic HTML structure
- Keyboard navigation support
- Screen reader friendly markup
- Clear visual feedback for selection states

82
docs/components/toast.md Normal file
View File

@@ -0,0 +1,82 @@
1. Home
2. Components
3. Drag Selectable
# Drag Selectable
A React component system that enables drag selection over a vertical list of items with toggle-based multi-select behavior.
## Live Example
Try the drag selection below:
- Normal drag: Toggle selection
- Ctrl/Cmd + drag: Replace selection
- Escape: Clear all selections
0 item s selected Clear All Learn React hooks Build a todo app Implement drag selection Style with Tailwind CSS Add dark mode support Write unit tests Deploy to production Add keyboard shortcuts Improve accessibility Add animations ```tsx
import React from 'react';
import { Card, Badge, useDragSelect } from '@vuer-ai/vuer-uikit';
const TODOS = [
{ key: "1", title: "Learn React hooks" },
{ key: "2", title: "Build a todo app" },
{ key: "3", title: "Implement drag selection" },
// ... more items
];
export default function DragSelectExample() {
const { selectedItems, getItemProps, clearSelection } = useDragSelect();
return (
<div>
<button onClick={clearSelection}>
Clear ({selectedItems.size} selected)
</button>
{TODOS.map(todo => (
<TodoItem
key={todo.key}
title={todo.title}
checked={selectedItems.has(todo.key)}
{...getItemProps(todo.key)}
/>
))}
</div>
);
}
```
## Simple API
The useDragSelect() hook provides everything you need for drag selection:
Returns:
- selectedItems: Set<string> - Currently selected item IDs
- getItemProps(id: string) - Props to spread on selectable items
- clearSelection() - Function to clear all selections
- isSelected(id: string) - Check if item is selected
Usage:
Just import the hook, call it, and spread getItemProps(id) on your items. The hook handles all the complex state management, event handling, and keyboard shortcuts automatically.
## Features
- Automatic Event Handling - Mouse and keyboard events handled internally
- Modifier Key Support - Ctrl/Cmd for replace mode, default toggle mode
- Global Events - Mouse up and Escape key work anywhere on page
- TypeScript Support - Fully typed hook and props
- Zero Dependencies - Pure React implementation
## Selection Modes
- Toggle (default): Items flip their selection state during drag
- Replace (Ctrl/Cmd + drag): Clear existing selection, start new selection range
## Accessibility
- Semantic HTML structure
- Keyboard navigation support
- Screen reader friendly markup
- Clear visual feedback for selection states

View File

@@ -0,0 +1,231 @@
1. Home
2. Components
3. Toggle Buttons
# Toggle Buttons
A set of buttons where only one can be selected at a time, with smooth animated transitions between selections.
## Props
### ToggleButtons
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| value | string | - | Controlled value |
| onValueChange | (value: string) => void | - | Callback when value changes |
| size | 'sm' | 'base' | 'lg' | 'base' | Size of the buttons |
| variant | 'primary' | 'secondary' | 'ghost' | 'secondary' | Visual style variant |
| padding | boolean | true | Whether to add padding between container and buttons |
| className | string | - | Custom CSS classes |
| children | ReactNode | - | ToggleButton components |
### ToggleButton
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| value | string | - | Value for this button |
| icon | boolean | false | If true, renders as square icon button with proper sizing |
| asChild | boolean | false | Render as child element (using Slot) |
| className | string | - | Custom CSS classes |
| children | ReactNode | - | Button content |
## Icon Only
Perfect for toolbar-style interfaces with square buttons:
Primary
Secondary
Ghost
Selected: select
```jsx
import { MousePointer, Hand, Scissors } from "lucide-react";
const [selectedTool, setSelectedTool] = useState("select");
return (
<div className="space-y-6">
<div className="space-y-2">
<p className="text-sm font-medium">Primary</p>
<ToggleButtons value={selectedTool} onValueChange={setSelectedTool} padding={false} variant="primary">
<ToggleButton value="select" icon>
<MousePointer className="size-4" />
</ToggleButton>
<ToggleButton value="pick" icon>
<Hand className="size-4" />
</ToggleButton>
<ToggleButton value="cut" icon>
<Scissors className="size-4" />
</ToggleButton>
</ToggleButtons>
</div>
<div className="space-y-2">
<p className="text-sm font-medium">Secondary</p>
<ToggleButtons value={selectedTool} onValueChange={setSelectedTool} padding={false} variant="secondary">
<ToggleButton value="select" icon>
<MousePointer className="size-4" />
</ToggleButton>
<ToggleButton value="pick" icon>
<Hand className="size-4" />
</ToggleButton>
<ToggleButton value="cut" icon>
<Scissors className="size-4" />
</ToggleButton>
</ToggleButtons>
</div>
<div className="space-y-2">
<p className="text-sm font-medium">Ghost</p>
<ToggleButtons value={selectedTool} onValueChange={setSelectedTool} padding={false} variant="ghost">
<ToggleButton value="select" icon>
<MousePointer className="size-4" />
</ToggleButton>
<ToggleButton value="pick" icon>
<Hand className="size-4" />
</ToggleButton>
<ToggleButton value="cut" icon>
<Scissors className="size-4" />
</ToggleButton>
</ToggleButtons>
</div>
</div>
);
```
## Usage
Select Pick Cut Selected: select
```jsx
const [selectedTool, setSelectedTool] = useState("select");
return (
<ToggleButtons value={selectedTool} onValueChange={setSelectedTool}>
<ToggleButton value="select">Select</ToggleButton>
<ToggleButton value="pick">Pick</ToggleButton>
<ToggleButton value="cut">Cut</ToggleButton>
</ToggleButtons>
);
```
## Padding Options
Control the spacing between the container and buttons:
With Padding (default)
Select Pick Cut Without Padding
Select Pick Cut Selected: select
```jsx
const [selectedTool, setSelectedTool] = useState("select");
return (
<>
{/* With padding (default) */}
<ToggleButtons value={selectedTool} onValueChange={setSelectedTool} padding={true} variant="primary">
<ToggleButton value="select">Select</ToggleButton>
<ToggleButton value="pick">Pick</ToggleButton>
<ToggleButton value="cut">Cut</ToggleButton>
</ToggleButtons>
{/* Without padding - buttons inherit full container size */}
<ToggleButtons value={selectedTool} onValueChange={setSelectedTool} padding={false} variant="primary">
<ToggleButton value="select">Select</ToggleButton>
<ToggleButton value="pick">Pick</ToggleButton>
<ToggleButton value="cut">Cut</ToggleButton>
</ToggleButtons>
</>
);
```
## Sizes
Small
Select Pick Cut Base
Select Pick Cut Large
Select Pick Cut Selected: select
```jsx
const [selectedTool, setSelectedTool] = useState("select");
return (
<>
<ToggleButtons size="sm" value={selectedTool} onValueChange={setSelectedTool}>
<ToggleButton value="select">Select</ToggleButton>
<ToggleButton value="pick">Pick</ToggleButton>
<ToggleButton value="cut">Cut</ToggleButton>
</ToggleButtons>
<ToggleButtons size="base" value={selectedTool} onValueChange={setSelectedTool}>
<ToggleButton value="select">Select</ToggleButton>
<ToggleButton value="pick">Pick</ToggleButton>
<ToggleButton value="cut">Cut</ToggleButton>
</ToggleButtons>
<ToggleButtons size="lg" value={selectedTool} onValueChange={setSelectedTool}>
<ToggleButton value="select">Select</ToggleButton>
<ToggleButton value="pick">Pick</ToggleButton>
<ToggleButton value="cut">Cut</ToggleButton>
</ToggleButtons>
</>
);
```
## Custom Styling
Select Pick Cut Selected: select
```jsx
const [selectedTool, setSelectedTool] = useState("select");
return (
<ToggleButtons
value={selectedTool}
onValueChange={setSelectedTool}
className="bg-blue-100 border-2 border-blue-300" // Custom container styles
>
<ToggleButton
value="select"
className="font-bold text-blue-600" // Custom item styles
>
Select
</ToggleButton>
<ToggleButton value="pick">Pick</ToggleButton>
<ToggleButton value="cut">Cut</ToggleButton>
</ToggleButtons>
);
```
## AsChild
Use asChild to render the toggle button as a different element while maintaining all functionality:
[Home](#home)[About](#about)[Contact](#contact)Selected: home
```jsx
const [selectedPage, setSelectedPage] = useState("home");
return (
<ToggleButtons value={selectedPage} onValueChange={setSelectedPage}>
<ToggleButton value="home" asChild>
<a href="#home">Home</a>
</ToggleButton>
<ToggleButton value="about" asChild>
<a href="#about">About</a>
</ToggleButton>
<ToggleButton value="contact" asChild>
<a href="#contact">Contact</a>
</ToggleButton>
</ToggleButtons>
);
```

View File

@@ -0,0 +1,110 @@
1. Home
2. Components
3. Toggle Group
# Toggle Group
A set of two-state buttons that can be toggled on or off. Toggle buttons share outer rounded corners with sharp inner corners, creating a seamless single-button appearance.
[Docs](https://www.radix-ui.com/primitives/docs/components/toggle-group)[API Reference](https://www.radix-ui.com/primitives/docs/components/toggle-group#api-reference)## Props
### ToggleGroup
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| etype | 'single' | 'multiple' | 'single' | Selection behavior |
| variant | 'primary' | 'secondary' | 'ghost' | 'primary' | Visual style passed to items |
| size | 'sm' | 'base' | 'lg' | 'base' | Size passed to items |
| ...Radix props | ComponentProps<typeof ToggleGroupPrimitive.Root> | - | All Radix group props |
### ToggleGroupItem
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| inherits | variant, size from group | - | Styling context from parent |
| ...Radix props | ComponentProps<typeof ToggleGroupPrimitive.Item> | - | All Radix item props |
Multiple buttons can be active at once with etype="multiple".
## Variants
### Primary (Default)
1 2 3 Selected: option-1
```jsx
<ToggleGroup variant="primary" type="multiple" size="sm">
<ToggleGroupItem value="option-1">1</ToggleGroupItem>
<ToggleGroupItem value="option-2">2</ToggleGroupItem>
<ToggleGroupItem value="option-3">3</ToggleGroupItem>
</ToggleGroup>
```
### Secondary
1 2 3 Selected: option-1
```jsx
<ToggleGroup variant="secondary" type="multiple" size="sm">
<ToggleGroupItem value="option-1">1</ToggleGroupItem>
<ToggleGroupItem value="option-2">2</ToggleGroupItem>
<ToggleGroupItem value="option-3">3</ToggleGroupItem>
</ToggleGroup>
```
### Ghost
1 2 3 Selected: option-1
```jsx
<ToggleGroup variant="ghost" type="multiple" size="sm">
<ToggleGroupItem value="option-1">1</ToggleGroupItem>
<ToggleGroupItem value="option-2">2</ToggleGroupItem>
<ToggleGroupItem value="option-3">3</ToggleGroupItem>
</ToggleGroup>
```
## Single Selection
Selected: center
```jsx
const [value, setValue] = useState("center");
<ToggleGroup variant="primary" type="single" size="sm" value={value} onValueChange={setValue}>
<ToggleGroupItem value="left"><AlignLeft className="size-3" /></ToggleGroupItem>
<ToggleGroupItem value="center"><AlignCenter className="size-3" /></ToggleGroupItem>
<ToggleGroupItem value="right"><AlignRight className="size-3" /></ToggleGroupItem>
<ToggleGroupItem value="justify"><AlignJustify className="size-3" /></ToggleGroupItem>
</ToggleGroup>
```
Only one button can be active at a time with etype="single".
## With Icons
Selected: list
```jsx
const [value, setValue] = useState(["view-1"]);
<ToggleGroup variant="primary" type="multiple" size="sm" value={value} onValueChange={setValue}>
<ToggleGroupItem value="list"><List className="size-3" /></ToggleGroupItem>
<ToggleGroupItem value="grid"><Grid className="size-3" /></ToggleGroupItem>
<ToggleGroupItem value="folder"><Folder className="size-3" /></ToggleGroupItem>
</ToggleGroup>
```
Toggle group with icon content.
## Disabled State
1 2 3 Selected: None
```jsx
<ToggleGroup variant="primary" type="multiple" size="sm">
<ToggleGroupItem value="option-1">1</ToggleGroupItem>
<ToggleGroupItem value="option-2" disabled>2</ToggleGroupItem>
<ToggleGroupItem value="option-3">3</ToggleGroupItem>
</ToggleGroup>
```

82
docs/components/toggle.md Normal file
View File

@@ -0,0 +1,82 @@
1. Home
2. Components
3. Drag Selectable
# Drag Selectable
A React component system that enables drag selection over a vertical list of items with toggle-based multi-select behavior.
## Live Example
Try the drag selection below:
- Normal drag: Toggle selection
- Ctrl/Cmd + drag: Replace selection
- Escape: Clear all selections
0 item s selected Clear All Learn React hooks Build a todo app Implement drag selection Style with Tailwind CSS Add dark mode support Write unit tests Deploy to production Add keyboard shortcuts Improve accessibility Add animations ```tsx
import React from 'react';
import { Card, Badge, useDragSelect } from '@vuer-ai/vuer-uikit';
const TODOS = [
{ key: "1", title: "Learn React hooks" },
{ key: "2", title: "Build a todo app" },
{ key: "3", title: "Implement drag selection" },
// ... more items
];
export default function DragSelectExample() {
const { selectedItems, getItemProps, clearSelection } = useDragSelect();
return (
<div>
<button onClick={clearSelection}>
Clear ({selectedItems.size} selected)
</button>
{TODOS.map(todo => (
<TodoItem
key={todo.key}
title={todo.title}
checked={selectedItems.has(todo.key)}
{...getItemProps(todo.key)}
/>
))}
</div>
);
}
```
## Simple API
The useDragSelect() hook provides everything you need for drag selection:
Returns:
- selectedItems: Set<string> - Currently selected item IDs
- getItemProps(id: string) - Props to spread on selectable items
- clearSelection() - Function to clear all selections
- isSelected(id: string) - Check if item is selected
Usage:
Just import the hook, call it, and spread getItemProps(id) on your items. The hook handles all the complex state management, event handling, and keyboard shortcuts automatically.
## Features
- Automatic Event Handling - Mouse and keyboard events handled internally
- Modifier Key Support - Ctrl/Cmd for replace mode, default toggle mode
- Global Events - Mouse up and Escape key work anywhere on page
- TypeScript Support - Fully typed hook and props
- Zero Dependencies - Pure React implementation
## Selection Modes
- Toggle (default): Items flip their selection state during drag
- Replace (Ctrl/Cmd + drag): Clear existing selection, start new selection range
## Accessibility
- Semantic HTML structure
- Keyboard navigation support
- Screen reader friendly markup
- Clear visual feedback for selection states

View File

@@ -0,0 +1,46 @@
1. Home
2. Components
3. Tooltip
# Tooltip
A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.
[Docs](https://www.radix-ui.com/primitives/docs/components/tooltip)[API Reference](https://www.radix-ui.com/primitives/docs/components/tooltip#api-reference)## Props
### Tooltip
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| ...Radix props | ComponentProps<typeof TooltipPrimitive.Root> | - | All Radix tooltip root props |
### TooltipContent
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| sideOffset | number | 0 | Offset in pixels from the trigger |
| ...Radix props | ComponentProps<typeof TooltipPrimitive.Content> | - | All Radix content props |
## Usage
Top Left Right Bottom ```jsx
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline">Top</Button>
</TooltipTrigger>
<TooltipContent side="top" align="start">
<p>Add to library</p>
</TooltipContent>
</Tooltip>
```
### Example
```jsx
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline">Hover</Button>
</TooltipTrigger>
<TooltipContent side="bottom">Hello</TooltipContent>
</Tooltip>
```

View File

@@ -0,0 +1,98 @@
1. Home
2. Components
3. Simple Tree View
# SimpleTreeView
## Types
```typescript
interface TreeDataItem {
id: string;
name: string;
icon?: IconComponent;
selectedIcon?: IconComponent;
openIcon?: IconComponent;
children?: TreeDataItem[];
actions?: ReactNode;
onClick?: () => void;
draggable?: boolean;
droppable?: boolean;
disabled?: boolean;
}
type IconComponent = React.ComponentType<{ className?: string }>;
```
# Simple Tree View
## Props
### SimpleTreeView
| Prop | Type | Description |
| --- | --- | --- |
| data | `TreeDataItem[] | TreeDataItem` |
| initialSelectedItemId | string | Preselect an item and auto-expand ancestors |
| onSelectChange | (item?: TreeDataItem) => void | Callback when selection changes |
| expandAll | boolean | Expand all nodes initially |
| defaultNodeIcon | IconComponent | Default icon for nodes |
| defaultLeafIcon | IconComponent | Default icon for leaves |
| onDocumentDrag | (source: TreeDataItem, target: TreeDataItem) => void | Drag and drop callback |
### TreeDataItem
```ts
type TreeDataItem = {
id: string;
name: string;
icon?: ComponentType<SVGProps<SVGSVGElement>>;
selectedIcon?: ComponentType<SVGProps<SVGSVGElement>>;
openIcon?: ComponentType<SVGProps<SVGSVGElement>>;
children?: TreeDataItem[];
actions?: React.ReactNode;
onClick?: () => void;
draggable?: boolean;
droppable?: boolean;
disabled?: boolean;
}
```
- Item 1
- Item 2
- Item 3
```jsx
const data = [
{ id: '1', name: 'Item 1', icon: ArrowRight,
children: [
{ id: '2', name: 'Item 1.1', icon: AlarmClock,
children: [
{ id: '3', name: 'Item 1.1.1', icon: Ambulance },
{ id: '4', name: 'Item 1.1.2', icon: Angry },
],
},
{ id: '5', name: 'Item 1.2 (disabled)', icon: Album, disabled: true },
],
}, {
id: '6', name: 'Item 2',
children: [
{ id: '7', name: 'Item 2.1', icon: AlignCenterHorizontal },
{ id: '8', name: 'Item 2.2', icon: Blend,
children: [
{ id: '9', name: 'Item 2.2.1', icon: Bird },
{ id: '10', name: 'Item 2.2.2', icon: Biohazard,
children: [
{ id: '11', name: 'Item 2.2.2.1', icon: Cannabis },
{ id: '12', name: 'Item 2.2.2.2 Item 2.2.2.2 Item 2.2.2.2 Item 2.2.2.2 Item 2.2.2.2', icon: Cannabis }
]
},
],
},
],
},
{ id: '13', name: 'Item 3' }
];
<SimpleTreeView data={treeData} className="w-[260px]" />
```

View File

@@ -0,0 +1,88 @@
1. Home
2. Components
3. Version Badge
# Version Badge
Displays the package version with git commit hash. Includes both a high-level component with boolean flags and a low-level component for custom values.
## High-Level Component (UIKitBadge)
Uses boolean flags to control which parts of the badge are displayed. All flags default to false - pass them as true to enable each element.
vuer-uikit [v0.0.117](https://www.npmjs.com/package/@vuer-ai/vuer-uikit/v/0.0.117)[2a52049](https://github.com/vuer-ai/vuer-uikit/commit/2a52049)vuer-uikit [v0.0.117](https://www.npmjs.com/package/@vuer-ai/vuer-uikit/v/0.0.117)vuer-uikit 0.0.1172a52049v0.0.117vuer-uikit 2a520490.0.117```jsx
// Full badge with all elements
<UIKitBadge package version prefix hash linkable />
// Package, version with prefix, clickable (no hash)
<UIKitBadge package version prefix linkable />
// Package, version without prefix, with hash
<UIKitBadge package version hash />
// Version with prefix only
<UIKitBadge version prefix />
// Package and hash only (no version)
<UIKitBadge package hash />
// Version only (no prefix)
<UIKitBadge version />
```
### Props
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| package | boolean | false | Show package name |
| version | boolean | false | Show version number |
| prefix | boolean | false | Add "v" prefix to version |
| hash | boolean | false | Show git commit hash |
| linkable | boolean | false | Make badge clickable (links to npm/github) |
| className | string | - | Additional CSS classes |
## Low-Level Component (PackageBadge)
Takes explicit values for full customization.
custom [v1.2.3](https://www.npmjs.com/package/@org/custom-package/v/1.2.3)[abc123](https://github.com/vuer-ai/vuer-uikit/commit/abc123)mylib 2.0.0v3.0.0-beta.1[def456](https://github.com/vuer-ai/vuer-uikit/commit/def456)```jsx
// Custom package with all values
<PackageBadge
packageName="custom"
versionText="v1.2.3"
gitHash="abc123"
packageFullName="@org/custom-package"
/>
// Non-linkable custom badge
<PackageBadge
packageName="mylib"
versionText="2.0.0"
linkable={false}
/>
// Version and hash only
<PackageBadge
versionText="v3.0.0-beta.1"
gitHash="def456"
/>
```
### Props
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| packageName | string | - | Package name to display |
| packageFullName | string | - | Full npm package name for link |
| versionText | string | - | Version string to display |
| gitHash | string | - | Git commit hash to display |
| linkable | boolean | true | Make badge clickable |
| className | string | - | Additional CSS classes |
## Programmatic Access
```jsx
import { PACKAGE_VERSION, GIT_HASH } from '@vuer-ai/vuer-uikit';
console.log(`Version: ${PACKAGE_VERSION}, Commit: ${GIT_HASH}`);
```

View File

@@ -0,0 +1,312 @@
1. Home
2. Components
3. Waterfall
# Waterfall
A hierarchical log display component for showing time-based log data with interactive controls and custom actions.
```typescript
interface WaterfallProps {
logData: LogItemType[];
temporalCursor?: number;
panelWidth?: number;
onTemporalCursorChange?: (time: number) => void;
getIcon: (item: LogItemType) => ReactNode;
hoveredId?: string | null;
onItemHover?: (id: string | null) => void;
minWindow?: number;
maxWindow?: number;
zoomFactor?: number;
enabled?: boolean;
children?: React.ReactNode;
className?: string;
}
```
## Types
```typescript
type LogItemType = TreeDataItemV2 & {
type: "task" | "attempt" | "info" | "step";
icon?: "history" | "file-code" | "bot" | "check-circle" | "pause-circle";
createTime?: number;
startTime?: number;
duration?: number;
time?: number;
color?: "blue" | "green" | "orange" | "gray-light" | "gray-medium" | "purple";
isCollapsible?: boolean;
hasStripes?: boolean;
isHaltedStep?: boolean;
};
type TreeDataItemV2 = {
id: string;
parentId: string | null;
label: string;
isCollapsible?: boolean;
actions?: ReactNode;
disable?: boolean;
[key: string]: unknown;
};
```
## Basic Usage
Job registered in queue generate-report Attempt 1 Fetch database records Job halted, waiting for resources... Waiting for image renderer... Render charts Assemble PDF Fetch database records Memory checkpoint data-validation Schema validation Data integrity check Generate validation report Cache cleared email-notification Prepare email template Attach report files Send via SMTP Webhook triggered System health check cleanup-process Remove temporary files Update job status All tasks completed -10s -5s 0ms 5s 10s 15s 20s 25s 30s 20.000s 19.900s 3.000s Halted 4.600s 6.200s 3.000s 12.000s 3.500s 33.000s ```jsx
import { Waterfall, LogItemType } from "@vuer-ai/vuer-uikit";
import React, { useState, useMemo } from "react";
import {
Bot,
CheckCircle2,
FileCode,
History,
Info,
PauseCircle,
Eye,
EyeClosed,
Trash2,
} from "lucide-react";
import { cn } from "@vuer-ai/vuer-uikit";
const logData: LogItemType[] = [
{
id: "0",
parentId: null,
indent: 0,
etype: "info",
label: "Job registered in queue",
icon: "history",
time: 0,
color: "purple",
},
{
id: "1",
parentId: null,
indent: 0,
etype: "task",
label: "generate-report",
icon: "file-code",
createTime: 0,
startTime: 0,
duration: 20,
color: "blue",
isCollapsible: true,
hasStripes: true,
},
{
id: "2",
parentId: "1",
indent: 1,
etype: "attempt",
label: "Attempt 1",
icon: "bot",
createTime: 0.1,
startTime: 0.1,
duration: 19.9,
color: "blue",
isCollapsible: true,
},
{
id: "3",
parentId: "2",
indent: 2,
etype: "step",
label: "Fetch database records",
icon: "check-circle",
createTime: 0.2,
startTime: 0.5,
duration: 3,
color: "green",
},
{
id: "4",
parentId: "2",
indent: 2,
etype: "step",
label: "Job halted, waiting for resources...",
icon: "pause-circle",
startTime: 4,
duration: 2,
color: "orange",
isHaltedStep: true,
},
// ... more log items
];
const getIcon = (item: LogItemType) => {
const iconColor = (item: LogItemType) => {
if (item.label === "generate-report" || item.label === "Assemble PDF")
return "text-blue-500";
if (item.icon === "file-code") return "text-muted-foreground";
return "";
};
switch (item.icon) {
case "history":
return <History className="size-4 text-purple-500 shrink-0" />;
case "file-code":
return <FileCode className={cn("size-4 shrink-0", iconColor(item))} />;
case "bot":
return <Bot className="size-4 text-muted-foreground shrink-0" />;
case "check-circle":
return <CheckCircle2 className="size-4 text-green-500 shrink-0" />;
case "pause-circle":
return <PauseCircle className="size-4 text-orange-500 shrink-0" />;
default:
return <Info className="size-4 text-muted-foreground shrink-0" />;
}
};
// Helper functions
const getAllChildrenIds = (parentId: string, allItems: LogItemType[]): string[] => {
const children: string[] = [];
const directChildren = allItems.filter(item => item.parentId === parentId);
for (const child of directChildren) {
children.push(child.id);
children.push(...getAllChildrenIds(child.id, allItems));
}
return children;
};
const isIndirectlyHidden = (itemId: string, hiddenItems: Set<string>, allItems: LogItemType[]): boolean => {
const item = allItems.find(i => i.id === itemId);
if (!item || !item.parentId) return false;
if (hiddenItems.has(item.parentId)) {
return true;
}
return isIndirectlyHidden(item.parentId, hiddenItems, allItems);
};
// State management
const [expandedItems, setExpandedItems] = useState(new Set(["1", "2"]));
const [hoveredId, setHoveredId] = useState<string | null>(null);
const [hiddenItems, setHiddenItems] = useState<Set<string>>(new Set());
const [deletedItems, setDeletedItems] = useState<Set<string>>(new Set());
// Toggle visibility function
const toggleItemVisibility = (itemId: string) => {
const wasHidden = hiddenItems.has(itemId);
setHiddenItems(prev => {
const newSet = new Set(prev);
if (newSet.has(itemId)) {
newSet.delete(itemId);
} else {
newSet.add(itemId);
}
return newSet;
});
// If hiding an expanded item, collapse it
if (!wasHidden && expandedItems.has(itemId)) {
setExpandedItems(prev => {
const newSet = new Set(prev);
newSet.delete(itemId);
return newSet;
});
}
};
// Delete item function
const deleteItem = (itemId: string) => {
const itemsToDelete = [itemId, ...getAllChildrenIds(itemId, logData)];
setDeletedItems(prev => {
const newSet = new Set(prev);
itemsToDelete.forEach(id => newSet.add(id));
return newSet;
});
setHiddenItems(prev => {
const newSet = new Set(prev);
itemsToDelete.forEach(id => newSet.delete(id));
return newSet;
});
setExpandedItems(prev => {
const newSet = new Set(prev);
itemsToDelete.forEach(id => newSet.delete(id));
return newSet;
});
};
// Create actions for each item
const createActions = (itemId: string, isDirectlyHidden: boolean, isIndirectlyHiddenItem: boolean, isHovered: boolean) => {
const visibilityButton = (
<button
onClick={(e) => {
e.stopPropagation();
toggleItemVisibility(itemId);
}}
className='hover:bg-shadow-secondary rounded p-1'
>
{isDirectlyHidden ? (
<EyeClosed className='text-icon-tertiary size-3' />
) : isIndirectlyHiddenItem ? (
<div className='flex size-4 items-center justify-center'>
<div className='text-icon-tertiary size-[3px] bg-current rounded-full' />
</div>
) : (
<Eye className='text-icon-primary size-3' />
)}
</button>
);
const deleteButton = (
<button
onClick={(e) => {
e.stopPropagation();
deleteItem(itemId);
}}
className='hover:bg-shadow-secondary rounded p-1'
>
<Trash2 className={cn('size-3',
(isDirectlyHidden || isIndirectlyHiddenItem) ? 'text-icon-tertiary' : 'text-icon-primary'
)} />
</button>
);
return (
<div className='flex gap-1'>
{isHovered && deleteButton}
{visibilityButton}
</div>
);
};
// Process log data with actions and visibility states
const processedLogData = useMemo(() => {
return logData
.filter(item => !deletedItems.has(item.id))
.map(item => {
const isDirectlyHidden = hiddenItems.has(item.id);
const isIndirectlyHiddenItem = isIndirectlyHidden(item.id, hiddenItems, logData);
const isItemHidden = isDirectlyHidden || isIndirectlyHiddenItem;
const isHovered = hoveredId === item.id;
return {
...item,
actions: createActions(item.id, isDirectlyHidden, isIndirectlyHiddenItem, isHovered),
disable: isItemHidden,
isSelectable: !isItemHidden,
};
});
}, [logData, deletedItems, hiddenItems, hoveredId]);
return (
<div className="w-full">
<Waterfall
className="h-[300px]"
logData={processedLogData}
getIcon={getIcon}
hoveredId={hoveredId}
onItemHover={setHoveredId}
/>
</div>
);
```