Token导航 LogoToken导航

Agent Skill · 研究检索

josechifflet-shadcn-ui(josechifflet shadcn/ui UI 搜索)

用于辅助界面设计、视觉规范、排版、配色、布局和交互体验优化。它适合让 Agent 根据产品场景整理页面结构、生成 UI 方案、检查视觉一致性或改进组件层级。使用时需要结合现有品牌、设计系统和用户任务,不应只堆装饰元素;涉及真实页面改动时,应通过截图或浏览器预览检查文本溢出、对齐和响应式表现。

josechifflet-shadcn-ui 是研究检索类 Agent Skill,可用宿主为 Local Agent,通过unknown获取,权限为需要联网;许可证信息还不明确,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 45,218。

总安装 864周安装 36下载 288核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:josechifflet-shadcn-ui(josechifflet shadcn/ui UI 搜索)
来源仓库:https://smithery.ai
仓库路径:josechifflet-shadcn-ui
安装命令:
# Install shadcn CLI
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 对应宿主 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.sh安装方式未标明
# Install shadcn CLI

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

josechifflet shadcn/ui UI 搜索提供组件设计规范与最佳实践指南。适合前端开发者构建类型安全、无障碍且移动端友好的界面。强调 Tailwind CSS 扩展、表单集成和响应式设计原则。使用前需已有 React + TypeScript 项目基础。建议复制而非导入组件,保持代码可控性。

来源仓库内路径:josechifflet-shadcn-ui

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Local Agent;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 # Install shadcn CLI;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

josechifflet-shadcn-ui 怎么安装?

在终端执行 # Install shadcn CLI。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

josechifflet-shadcn-ui 支持哪些 AI 工具?

公开资料标注支持 Local Agent。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

josechifflet-shadcn-ui 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

josechifflet-shadcn-ui 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

josechifflet-shadcn-ui 用的人多吗?

公开数据是累计安装 864 次,近一周安装 36 次,下载 288 次。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

josechifflet-shadcn-ui 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 专注 Local Agent 一种宿主,触发方式和使用习惯不用来回切换。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Local Agent,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
josechifflet-shadcn-ui

josechifflet shadcn/ui UI 搜索 · 本页

864—需要联网未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

shadcn/ui Component Usage

Purpose

Provide comprehensive patterns for implementing shadcn/ui components in Next.js 16 applications with Atlas-specific conventions. Focus on composition over props, accessibility-first design, and type-safe integration with tRPC and react-hook-form.

When To Use This Skill

Component Implementation:

  • Adding new shadcn/ui components to the project
  • Customizing component variants and styles
  • Building composite components from primitives (Dialog, Form, Table)
  • Implementing responsive mobile/desktop patterns

Form Integration:

  • Integrating react-hook-form with shadcn Form components
  • Validating forms with Zod schemas
  • Connecting forms to tRPC mutations
  • Handling form state and errors

Data Display:

  • Creating data tables with sorting and filtering
  • Building card layouts and list views
  • Implementing skeleton loading states

Interactive Patterns:

  • Building modal dialogs and drawers (sheets)
  • Implementing toast notifications
  • Creating dropdown menus and popovers
  • Adding tooltips and hover states

Accessibility:

  • Ensuring keyboard navigation works correctly
  • Adding proper ARIA labels (especially icon buttons)
  • Implementing focus management
  • Meeting WCAG 2.1 AAA standards (44px minimum touch targets)

Core Principles

1. Copy-Not-Import Philosophy

shadcn/ui components are copied into the project, not imported as dependencies. Customize directly in src/components/ui/.

// ✅ Customize directly
// src/components/ui/button.tsx
const buttonVariants = cva("...", {
  variants: {
    variant: {
      default: "bg-primary text-primary-foreground",
      // Add your custom variant
      atlas: "bg-blue-600 text-white hover:bg-blue-700",
    },
  },
});

2. Composition Over Props

Build complex components by composing primitives rather than adding props:

// ❌ Avoid: Too many props
<Dialog
  title="Delete Item"
  description="Are you sure?"
  showCloseButton={true}
  size="lg"
/>

// ✅ Prefer: Composition
<Dialog>
  <DialogContent>
    <DialogHeader>
      <DialogTitle>Delete Item</DialogTitle>
      <DialogDescription>Are you sure?</DialogDescription>
    </DialogHeader>
  </DialogContent>
</Dialog>

3. className Customization

Extend styles via className prop using Tailwind utilities:

<Button variant="default" className="w-full sm:w-auto shadow-lg">
  Submit
</Button>

4. Accessibility First

All components are accessible by default (built on Radix UI):

  • Keyboard navigation
  • Screen reader support
  • ARIA attributes
  • Focus management

Icon buttons require labels for accessibility:

// ❌ Inaccessible
<Button size="icon">
  <TrashIcon />
</Button>

// ✅ Accessible
<Button size="icon" aria-label="Delete item">
  <TrashIcon />
</Button>

Quick Reference

Common Components

ComponentUse CaseKey Features
ButtonActions, triggersVariants, sizes, loading state
InputText entryTypes, validation states
FormForm validationreact-hook-form integration
DialogModalsPortal, overlay, animations
SheetSide panelsMobile-friendly drawers
TableData displaySemantic HTML, responsive
SelectDropdownsSearchable, keyboard nav
CheckboxBoolean inputIndeterminate state
LabelForm labelsAuto-linked to inputs
TextareaMulti-line inputAuto-resize support
TabsNavigationKeyboard accessible
CardContent containersHeader, content, footer
BadgeStatus labelsVariants for states
SkeletonLoading statesPlaceholder UI
SeparatorVisual dividersHorizontal/vertical
Dropdown MenuActions menuNested menus, shortcuts
AlertNotificationsInfo, warning, error
ProgressLoading indicatorsDeterminate/indeterminate
TooltipHover hintsDelay, positioning

Button Variants & Sizes

<Button variant="default">Primary Action</Button>
<Button variant="secondary">Secondary Action</Button>
<Button variant="outline">Outlined</Button>
<Button variant="ghost">Subtle</Button>
<Button variant="destructive">Delete</Button>
<Button variant="link">Link Style</Button>

<Button size="sm">Small</Button>      {/* 32px mobile, 40px desktop */}
<Button size="default">Default</Button> {/* 44px mobile, 36px desktop */}
<Button size="lg">Large</Button>      {/* 48px mobile, 40px desktop */}
<Button size="icon" aria-label="Add"> {/* 44x44px - WCAG 2.1 AAA */}
  <PlusIcon />
</Button>

Loading States

<Button loading={isPending} loadingText="Saving...">
  Save Changes
</Button>

// Or manually:
<Button disabled={isPending}>
  {isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
  Save Changes
</Button>

Form Integration

Basic Form Pattern

"use client";

import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";

const schema = z.object({
  email: z.string().email(),
  name: z.string().min(2),
});

type FormValues = z.infer<typeof schema>;

export function MyFormClient() {
  const form = useForm<FormValues>({
    resolver: zodResolver(schema),
    defaultValues: { email: "", name: "" },
  });

  const onSubmit = form.handleSubmit(async (data) => {
    // Handle submission
  });

  return (
    <Form {...form}>
      <form onSubmit={onSubmit} className="space-y-4">
        <FormField
          control={form.control}
          name="email"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Email</FormLabel>
              <FormControl>
                <Input type="email" placeholder="you@example.com" {...field} />
              </FormControl>
              <FormDescription>We'll never share your email.</FormDescription>
              <FormMessage />
            </FormItem>
          )}
        />

        <Button type="submit" loading={form.formState.isSubmitting}>
          Submit
        </Button>
      </form>
    </Form>
  );
}

Form with tRPC Mutation

"use client";

import { api } from "@/lib/api/react";
import { toast } from "sonner";

export function CreateStackFormClient() {
  const form = useForm<FormValues>({
    resolver: zodResolver(schema),
    defaultValues: {
      /* ... */
    },
  });

  const utils = api.useUtils();
  const createMutation = api.stacks.create.useMutation({
    onSuccess: () => {
      toast.success("Stack created successfully");
      utils.stacks.list.invalidate(); // Refetch list
      form.reset();
    },
    onError: (error) => {
      toast.error(error.message);
    },
  });

  const onSubmit = form.handleSubmit((data) => {
    createMutation.mutate(data);
  });

  return (
    <Form {...form}>
      <form onSubmit={onSubmit} className="space-y-4">
        {/* Form fields */}
        <Button
          type="submit"
          loading={createMutation.isPending}
          disabled={createMutation.isPending}
        >
          Create Stack
        </Button>
      </form>
    </Form>
  );
}

Common Form Field Patterns

Number Input:

<FormField
  control={form.control}
  name="quantity"
  render={({ field }) => (
    <FormItem>
      <FormLabel>Quantity</FormLabel>
      <FormControl>
        <Input
          type="number"
          inputMode="numeric"
          placeholder="100"
          {...field}
          onChange={(e) => field.onChange(e.target.valueAsNumber)}
        />
      </FormControl>
      <FormMessage />
    </FormItem>
  )}
/>

Date Input:

<FormField
  control={form.control}
  name="scheduledFor"
  render={({ field: { value, onChange, ...field } }) => (
    <FormItem>
      <FormLabel>Scheduled Date</FormLabel>
      <FormControl>
        <Input
          type="date"
          {...field}
          value={value instanceof Date ? value.toISOString().split("T")[0] : ""}
          onChange={(e) => {
            const dateStr = e.target.value;
            if (dateStr) onChange(new Date(dateStr));
          }}
        />
      </FormControl>
      <FormMessage />
    </FormItem>
  )}
/>

Select/Dropdown:

import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";

<FormField
  control={form.control}
  name="status"
  render={({ field }) => (
    <FormItem>
      <FormLabel>Status</FormLabel>
      <Select onValueChange={field.onChange} defaultValue={field.value}>
        <FormControl>
          <SelectTrigger>
            <SelectValue placeholder="Select a status" />
          </SelectTrigger>
        </FormControl>
        <SelectContent>
          <SelectItem value="active">Active</SelectItem>
          <SelectItem value="inactive">Inactive</SelectItem>
        </SelectContent>
      </Select>
      <FormMessage />
    </FormItem>
  )}
/>;

Textarea:

import { Textarea } from "@/components/ui/textarea";

<FormField
  control={form.control}
  name="notes"
  render={({ field }) => (
    <FormItem>
      <FormLabel>Notes</FormLabel>
      <FormControl>
        <Textarea placeholder="Optional notes..." maxLength={1000} {...field} />
      </FormControl>
      <FormMessage />
    </FormItem>
  )}
/>;

Checkbox:

import { Checkbox } from "@/components/ui/checkbox";

<FormField
  control={form.control}
  name="acceptTerms"
  render={({ field }) => (
    <FormItem className="flex flex-row items-start gap-3 space-y-0">
      <FormControl>
        <Checkbox checked={field.value} onCheckedChange={field.onChange} />
      </FormControl>
      <div className="space-y-1 leading-none">
        <FormLabel>Accept terms and conditions</FormLabel>
        <FormDescription>You agree to our Terms of Service.</FormDescription>
      </div>
    </FormItem>
  )}
/>;

Dialog Patterns

Basic Dialog

import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";

<Dialog>
  <DialogTrigger asChild>
    <Button variant="outline">Open Dialog</Button>
  </DialogTrigger>
  <DialogContent>
    <DialogHeader>
      <DialogTitle>Are you sure?</DialogTitle>
      <DialogDescription>This action cannot be undone.</DialogDescription>
    </DialogHeader>
    <DialogFooter>
      <Button variant="outline">Cancel</Button>
      <Button variant="destructive">Delete</Button>
    </DialogFooter>
  </DialogContent>
</Dialog>;

Controlled Dialog with Form

"use client";

import { useState } from "react";

export function CreateDialogClient() {
  const [open, setOpen] = useState(false);
  const form = useForm({
    /* ... */
  });

  const createMutation = api.stacks.create.useMutation({
    onSuccess: () => {
      toast.success("Created successfully");
      form.reset();
      setOpen(false); // Close dialog
    },
  });

  const onSubmit = form.handleSubmit((data) => {
    createMutation.mutate(data);
  });

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogTrigger asChild>
        <Button>Create New</Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Create Stack</DialogTitle>
          <DialogDescription>Add a new stack to the system.</DialogDescription>
        </DialogHeader>

        <Form {...form}>
          <form onSubmit={onSubmit} className="space-y-4">
            {/* Form fields */}
            <DialogFooter>
              <Button
                type="button"
                variant="outline"
                onClick={() => setOpen(false)}
                disabled={createMutation.isPending}
              >
                Cancel
              </Button>
              <Button type="submit" loading={createMutation.isPending}>
                Create
              </Button>
            </DialogFooter>
          </form>
        </Form>
      </DialogContent>
    </Dialog>
  );
}

Responsive Dialog/Sheet

Atlas has a custom ResponsiveDialogSheet that shows Dialog on desktop, Sheet on mobile:

import { ResponsiveDialogSheet } from "@/components/features/common";

<ResponsiveDialogSheet
  open={open}
  onOpenChange={setOpen}
  title="Create Stack"
  description="Add a new stack to the system"
  trigger={<Button>Open</Button>}
>
  {/* Content - works on both desktop and mobile */}
  <Form {...form}>
    <form onSubmit={onSubmit}>{/* Fields */}</form>
  </Form>
</ResponsiveDialogSheet>;

Data Table Patterns

Basic Table

import {
  Table,
  TableBody,
  TableCaption,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";

<Table>
  <TableCaption>A list of your recent invoices.</TableCaption>
  <TableHeader>
    <TableRow>
      <TableHead>Invoice</TableHead>
      <TableHead>Status</TableHead>
      <TableHead className="text-right">Amount</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    {invoices.map((invoice) => (
      <TableRow key={invoice.id}>
        <TableCell>{invoice.invoice}</TableCell>
        <TableCell>{invoice.status}</TableCell>
        <TableCell className="text-right">{invoice.amount}</TableCell>
      </TableRow>
    ))}
  </TableBody>
</Table>;

Loading Skeleton

import { Skeleton } from "@/components/ui/skeleton";

if (isLoading) {
  return (
    <div className="space-y-3">
      <Skeleton className="h-10 w-full" />
      <Skeleton className="h-10 w-full" />
      <Skeleton className="h-10 w-full" />
    </div>
  );
}

Toast Notifications

Atlas uses Sonner for toast notifications:

import { toast } from "sonner";

// Success
toast.success("Stack created successfully");

// Error
toast.error("Failed to create stack");

// Info
toast.info("Processing your request...");

// Warning
toast.warning("This action is irreversible");

// With action
toast.success("Stack deleted", {
  action: {
    label: "Undo",
    onClick: () => {
      /* Undo logic */
    },
  },
});

// Promise toast (auto-updates based on promise state)
toast.promise(createMutation.mutateAsync(data), {
  loading: "Creating stack...",
  success: "Stack created successfully",
  error: "Failed to create stack",
});

Styling Patterns

Responsive Design

<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
  {/* Mobile: 1 column, Tablet: 2 columns, Desktop: 3 columns */}
</div>

<Button className="w-full sm:w-auto">
  {/* Full width on mobile, auto on desktop */}
</Button>

Conditional Styles with cn()

import { cn } from "@/lib/utils";

<Button
  className={cn(
    "base-classes",
    isActive && "bg-blue-600",
    isDisabled && "opacity-50 cursor-not-allowed",
    variant === "large" && "text-lg px-6",
  )}
>
  Click me
</Button>;

Dark Mode Support

All shadcn components support dark mode automatically via CSS variables:

<div className="bg-background text-foreground">
  {/* Automatically adapts to light/dark mode */}
</div>

Common Mistakes

❌ Missing aria-label on icon buttons

// Bad
<Button size="icon"><TrashIcon /></Button>

// Good
<Button size="icon" aria-label="Delete item"><TrashIcon /></Button>

❌ Not using FormControl

// Bad - missing ARIA attributes
<FormField
  control={form.control}
  name="email"
  render={({ field }) => (
    <FormItem>
      <FormLabel>Email</FormLabel>
      <Input {...field} />  {/* Missing FormControl */}
      <FormMessage />
    </FormItem>
  )}
/>

// Good - proper ARIA linkage
<FormField
  control={form.control}
  name="email"
  render={({ field }) => (
    <FormItem>
      <FormLabel>Email</FormLabel>
      <FormControl>
        <Input {...field} />
      </FormControl>
      <FormMessage />
    </FormItem>
  )}
/>

❌ Forgetting DialogTrigger asChild

// Bad - creates nested button
<DialogTrigger><Button>Open</Button></DialogTrigger>

// Good - merges props into Button
<DialogTrigger asChild><Button>Open</Button></DialogTrigger>

Installation

# Install shadcn CLI
pnpm dlx shadcn@latest init

# Add components
pnpm dlx shadcn@latest add button input form dialog table select checkbox textarea label

Resources

  • Official docs: https://ui.shadcn.com
  • Examples: See references/examples.md
  • Recipes: See references/recipes.md
  • Patterns: See references/patterns.md
  • Atlas patterns: @/framework/patterns/shadcn.md

Summary

Key practices:

  1. Copy, don't import - customize in src/components/ui/
  2. Compose, don't prop - build from primitives
  3. className over props - extend with Tailwind
  4. Accessibility first - labels on icon buttons
  5. Forms with react-hook-form - use Form components
  6. Mobile-first - 44px minimum touch targets
  7. Type-safe - derive types from tRPC RouterOutputs

平台分布

Local Agent

93.56%
按下载量换算269

安全审计

Socket

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills