OpenClaw Skillv1.0.0

Shadcn Ui

jgarrison929by jgarrison929
Deploy on EasyClawdfrom $14.9/mo

Use when building UI with shadcn/ui components, Tailwind CSS layouts, form patterns with react-hook-form and zod, theming, dark mode, sidebar layouts, mobile navigation, or any shadcn component question.

How to use this skill

OpenClaw skills run inside an OpenClaw container. EasyClawd deploys and manages yours — no server setup needed.

  1. Sign up on EasyClawd (2 minutes)
  2. Connect your Telegram bot
  3. Install Shadcn Ui from the skills panel
Get started — from $14.9/mo
6stars
5,362downloads
34installs
0comments
1versions

Latest Changelog

shadcn-ui 1.0.0 – Initial Release

- Provides expert guidance for building UIs with shadcn/ui, Tailwind CSS, react-hook-form, and zod.
- Covers installation steps, component categories, and usage best practices.
- Includes detailed component tables for layout, navigation, data display, forms, actions, and feedback.
- Offers a complete react-hook-form + zod form pattern example using shadcn/ui components.
- Supports theming, dark mode, sidebar layouts, and mobile navigation use cases.
- Triggered by keywords like shadcn, radix, UI components, form pattern, and theming.

Tags

latest: 1.0.0

Skill Documentation

---
name: shadcn-ui
version: 1.0.0
description: Use when building UI with shadcn/ui components, Tailwind CSS layouts, form patterns with react-hook-form and zod, theming, dark mode, sidebar layouts, mobile navigation, or any shadcn component question.
triggers:
  - shadcn
  - shadcn/ui
  - radix
  - component library
  - UI components
  - form pattern
  - react-hook-form
  - dark mode
  - theming
  - sidebar layout
  - dialog
  - sheet
  - toast
  - dropdown menu
  - command palette
  - data table
role: specialist
scope: implementation
output-format: code
---

# shadcn/ui Expert

Comprehensive guide for building production UIs with shadcn/ui, Tailwind CSS, react-hook-form, and zod.

## Core Concepts

shadcn/ui is **not** a component library — it's a collection of copy-paste components built on Radix UI primitives. You own the code. Components are added to your project, not installed as dependencies.

## Installation

```bash
# Initialize shadcn/ui in a Next.js project
npx shadcn@latest init

# Add individual components
npx shadcn@latest add button
npx shadcn@latest add card
npx shadcn@latest add dialog
npx shadcn@latest add form
npx shadcn@latest add input
npx shadcn@latest add select
npx shadcn@latest add table
npx shadcn@latest add toast
npx shadcn@latest add dropdown-menu
npx shadcn@latest add sheet
npx shadcn@latest add tabs
npx shadcn@latest add sidebar

# Add multiple at once
npx shadcn@latest add button card input label textarea select checkbox
```

---

## Component Categories & When to Use

### Layout & Navigation
| Component | Use When |
|-----------|----------|
| `sidebar` | App-level navigation with collapsible sections |
| `navigation-menu` | Top-level site navigation with dropdowns |
| `breadcrumb` | Showing page hierarchy/location |
| `tabs` | Switching between related views in same context |
| `separator` | Visual divider between content sections |
| `sheet` | Slide-out panel (mobile nav, filters, detail views) |
| `resizable` | Adjustable panel layouts |

### Forms & Input
| Component | Use When |
|-----------|----------|
| `form` | Any form with validation (wraps react-hook-form) |
| `input` | Text, email, password, number inputs |
| `textarea` | Multi-line text input |
| `select` | Choosing from a list (native-like) |
| `combobox` | Searchable select (uses `command` + `popover`) |
| `checkbox` | Boolean or multi-select toggles |
| `radio-group` | Single selection from small set |
| `switch` | On/off toggle (settings, preferences) |
| `slider` | Numeric range selection |
| `date-picker` | Date selection (uses `calendar` + `popover`) |
| `toggle` | Pressed/unpressed state (toolbar buttons) |

### Feedback & Overlay
| Component | Use When |
|-----------|----------|
| `dialog` | Modal confirmation, forms, or detail views |
| `alert-dialog` | Destructive action confirmation ("Are you sure?") |
| `sheet` | Side panel for forms, filters, mobile nav |
| `toast` | Brief non-blocking notifications (via `sonner`) |
| `alert` | Inline status messages (info, warning, error) |
| `tooltip` | Hover hints for icons/buttons |
| `popover` | Rich content on click (color pickers, date pickers) |
| `hover-card` | Preview content on hover (user profiles, links) |
| `skeleton` | Loading placeholders |
| `progress` | Task completion indicators |

### Data Display
| Component | Use When |
|-----------|----------|
| `table` | Tabular data display |
| `data-table` | Tables with sorting, filtering, pagination (uses `@tanstack/react-table`) |
| `card` | Content containers with header, body, footer |
| `badge` | Status labels, tags, counts |
| `avatar` | User profile images |
| `accordion` | Collapsible FAQ or settings sections |
| `carousel` | Image/content slideshows |
| `scroll-area` | Custom scrollable containers |

### Actions
| Component | Use When |
|-----------|----------|
| `button` | Primary actions, form submissions |
| `dropdown-menu` | Context menus, action menus |
| `context-menu` | Right-click menus |
| `menubar` | Application menu bars |
| `command` | Command palette / search (⌘K) |

---

## Form Patterns (react-hook-form + zod)

### Complete Form Example

```bash
npx shadcn@latest add form input select textarea checkbox button
```

```tsx
'use client'

import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import { z } from 'zod'
import { Button } from '@/components/ui/button'
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import { Checkbox } from '@/components/ui/checkbox'
import { toast } from 'sonner'

const formSchema = z.object({
  name: z.string().min(2, 'Name must be at least 2 characters'),
  email: z.string().email('Invalid email address'),
  role: z.enum(['admin', 'user', 'editor'], { required_error: 'Select a role' }),
  bio: z.string().max(500).optional(),
  notifications: z.boolean().default(false),
})

type FormValues = z.infer<typeof formSchema>

export function UserForm() {
  const form = useForm<FormValues>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      name: '',
      email: '',
      bio: '',
      notifications: false,
    },
  })

  async function onSubmit(values: FormValues) {
    try {
      await createUser(values)
      toast.success('User created successfully')
      form.reset()
    } catch (error) {
      toast.error('Failed to create user')
    }
  }

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
        <FormField
          control={form.control}
          name="name"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Name</FormLabel>
              <FormControl>
                <Input placeholder="John Doe" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />

        <FormField
          control={form.control}
          name="email"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Email</FormLabel>
              <FormControl>
                <Input type="email" placeholder="[email protected]" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />

        <FormField
          control={form.control}
          name="role"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Role</FormLabel>
              <Select onValueChange={field.onChange} defaultValue={field.value}>
                <FormControl>
                  <SelectTrigger>
                    <SelectValue placeholder="Select a role" />
                  </SelectTrigger>
                </FormControl>
                <SelectContent>
                  <SelectItem value="admin">Admin</SelectItem>
                  <SelectItem value="editor">Editor</SelectItem>
                  <SelectItem value="user">User</SelectItem>
                </SelectContent>
              </Select>
              <FormMessage />
            </FormItem>
          )}
        />

        <FormField
          control={form.control}
          name="bio"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Bio</FormLabel>
              <FormControl>
                <Textarea placeholder="Tell us about yourself..." {...field} />
              </FormControl>
              <FormDescription>Max 500 characters</FormDescription>
              <FormMessage />
            </FormItem>
          )}
        />

        <FormField
          control={form.control}
          name="notifications"
          render={({ field }) => (
            <FormItem className="flex flex-row items-start space-x-3 space-y-0">
              <FormContro
Read full documentation on ClawHub
Security scan, version history, and community comments: view on ClawHub