| name | new-component |
| description | Scaffold a new AI element or UI component following project conventions. Use when asked to create a new component, add a component, scaffold a component, or build a new UI element. Use when this capability is needed. |
| metadata | {"author":"davincidreams"} |
New Component Skill
Scaffold new components in this project. There are two component categories with distinct conventions.
Step 1: Determine Component Category
Ask the user (if not already clear) which category:
- AI Element (
components/ai-elements/) - Domain-specific components for the generative UI chat experience (messages, code blocks, tools, panels, etc.)
- UI Primitive (
components/ui/) - Reusable, generic UI primitives built on Radix UI / shadcn patterns (buttons, inputs, dialogs, etc.)
Step 2: Scaffold the Component
AI Element Convention
File: components/ai-elements/{kebab-case-name}.tsx
Pattern to follow:
"use client";
import type { ComponentProps, HTMLAttributes } from "react";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { SomeIcon } from "lucide-react";
import { memo, useCallback, useMemo, useState } from "react";
export type MyComponentProps = HTMLAttributes<HTMLDivElement> & {
};
export const MyComponent = ({ className, children, ...props }: MyComponentProps) => (
<div className={cn("base-tailwind-classes", className)} {...props}>
{children}
</div>
);
Key conventions for AI elements:
- Always start with
"use client";
- Use
cn() from @/lib/utils for all className merging
- Export both the prop type (
export type XProps) and the component (export const X)
- Compose with UI primitives from
@/components/ui/ (Button, Card, Badge, etc.)
- Use
lucide-react for icons
- Use
motion (from motion/react) for animations
- For interactive state, use Zustand hooks from
@/lib/store.ts when the state needs to be shared across the app
- Use React hooks (
useState, useCallback, useMemo, useRef) for local state
UI Primitive Convention
File: components/ui/{kebab-case-name}.tsx
For UI primitives, prefer using the shadcn CLI:
npx shadcn@latest add <component-name>
This auto-generates components in components/ui/ following the project's components.json config (new-york style, Tailwind CSS variables, lucide icons).
If creating a custom UI primitive (not available in shadcn), follow this pattern:
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { Slot } from "radix-ui"
import { cn } from "@/lib/utils"
const myComponentVariants = cva(
"base-classes",
{
variants: {
variant: {
default: "default-classes",
secondary: "secondary-classes",
},
size: {
default: "default-size-classes",
sm: "sm-classes",
lg: "lg-classes",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
function MyComponent({
className,
variant = "default",
size = "default",
asChild = false,
...props
}: React.ComponentProps<"div"> &
VariantProps< myComponentVariants> & {
asChild?:
}) {
= asChild ? . :
(
)
}
{ , myComponentVariants }
Key conventions for UI primitives:
- Use
function declarations (not arrow functions)
- Use
data-slot attributes for styling hooks
- Use
cva() for variants
- Support
asChild pattern via Slot.Root from radix-ui
- Export both the component and its variants
- No
"use client" unless the component uses hooks/state
Step 3: Verify
After creating the component:
- Read back the created file to confirm correctness
- Run
npx tsc --noEmit to verify no type errors
- Run
npx eslint <file-path> to verify lint passes
Available UI Primitives
These exist in components/ui/ and can be imported by AI elements:
accordion, alert, avatar, badge, button, button-group, card, carousel, collapsible, command, dialog, dropdown-menu, hover-card, input, input-group, popover, progress, scroll-area, select, separator, spinner, switch, tabs, textarea, tooltip
Existing AI Elements
These exist in components/ai-elements/ for reference:
agent, artifact, attachments, audio-player, canvas, chain-of-thought, checkpoint, code-block, commit, confirmation, connection, context, controls, conversation, edge, environment-variables, file-tree, generative-message, image, inline-citation, jsx-preview, message, mic-selector, model-selector, node, open-in-chat, package-info, panel, persona, plan, prompt-input, queue, reasoning, sandbox, schema-display, shimmer, snippet, sources, speech-input, stack-trace, suggestion, task, terminal, test-results, tool, toolbar, transcription, voice-selector, web-preview
Converted and distributed by TomeVault — claim your Tome and manage your conversions.