-

Agent Template Card

PreviousNext

A template card for agent marketplaces, starter kits, and internal playbooks.

Installation

pnpm
pnpm dlx shadcn@latest add https://ui.zgi.ai/r/agent-template-card.json
npm
pnpm dlx shadcn@latest add https://ui.zgi.ai/r/agent-template-card.json
yarn
yarn dlx shadcn@latest add https://ui.zgi.ai/r/agent-template-card.json

Component

components/ui/agent-template-card.tsx
"use client"

import * as React from "react"
import { BotIcon, EyeIcon, SparklesIcon } from "lucide-react"

import { cn } from "@/lib/utils"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Card, CardContent } from "@/components/ui/card"

export interface AgentTemplateCardProps
  extends Omit<React.ComponentProps<typeof Card>, "title"> {
  title: React.ReactNode
  description?: React.ReactNode
  category?: React.ReactNode
  icon?: React.ReactNode
  labels?: React.ReactNode[]
  tools?: number
  workflows?: number
  onUse?: () => void
  onPreview?: () => void
  useLabel?: React.ReactNode
  previewLabel?: React.ReactNode
}

export function AgentTemplateCard({
  title,
  description,
  category,
  icon,
  labels = [],
  tools,
  workflows,
  onUse,
  onPreview,
  useLabel = "Use template",
  previewLabel = "Preview",
  className,
  ...props
}: AgentTemplateCardProps) {
  return (
    <Card className={cn("rounded-lg py-0", className)} {...props}>
      <CardContent className="flex min-h-56 flex-col gap-4 p-4">
        <div className="flex items-start gap-3">
          <div className="bg-primary/10 text-primary flex size-11 shrink-0 items-center justify-center rounded-lg">
            {icon ?? <BotIcon className="size-5" />}
          </div>
          <div className="min-w-0 flex-1">
            <div className="flex min-w-0 flex-wrap items-center gap-2">
              <h3 className="truncate text-sm font-medium">{title}</h3>
              {category ? (
                <Badge variant="outline" className="h-6 rounded-md">
                  {category}
                </Badge>
              ) : null}
            </div>
            {description ? (
              <p className="text-muted-foreground mt-1 line-clamp-3 text-xs leading-5">
                {description}
              </p>
            ) : null}
          </div>
        </div>

        <div className="flex flex-wrap gap-1.5">
          {labels.map((label, index) => (
            <Badge
              key={index}
              variant="secondary"
              className="h-6 rounded-md px-2 font-normal"
            >
              {label}
            </Badge>
          ))}
        </div>

        <div className="mt-auto grid grid-cols-2 gap-2 text-xs">
          {typeof tools === "number" ? (
            <div className="rounded-md border p-2">
              <div className="text-muted-foreground">Tools</div>
              <div className="mt-1 font-medium tabular-nums">{tools}</div>
            </div>
          ) : null}
          {typeof workflows === "number" ? (
            <div className="rounded-md border p-2">
              <div className="text-muted-foreground">Workflows</div>
              <div className="mt-1 font-medium tabular-nums">{workflows}</div>
            </div>
          ) : null}
        </div>

        <div className="flex gap-2 border-t pt-3">
          <Button
            type="button"
            size="sm"
            className="h-8 flex-1 gap-2 rounded-md"
            onClick={onUse}
          >
            <SparklesIcon className="size-3.5" />
            {useLabel}
          </Button>
          <Button
            type="button"
            variant="outline"
            size="sm"
            className="h-8 gap-2 rounded-md"
            onClick={onPreview}
          >
            <EyeIcon className="size-3.5" />
            {previewLabel}
          </Button>
        </div>
      </CardContent>
    </Card>
  )
}

Usage

import { AgentTemplateCard } from "@/components/ui/agent-template-card"
 
export function Example() {
  return (
    <AgentTemplateCard
      title="Support Concierge"
      category="Support"
      labels={["RAG", "Handoff"]}
      tools={5}
      workflows={2}
    />
  )
}

Props

PropTypeDefault
titleReactNoderequired
descriptionReactNode-
categoryReactNode-
iconReactNode-
labelsReactNode[][]
toolsnumber-
workflowsnumber-
onUse() => void-
onPreview() => void-