feat: update skills

This commit is contained in:
shadcn
2026-02-27 11:45:50 +04:00
parent 40ab22fded
commit c2f28e3ef5
5 changed files with 220 additions and 25 deletions

View File

@@ -75,15 +75,26 @@ shadcn docs button dialog select
1. **Get project context** — already injected above. Run `shadcn info` again if you need to refresh.
2. **Check installed components** — look in the `resolvedPaths.ui` directory before importing or adding. Don't import components that haven't been added, and don't re-add ones already installed.
3. **Find components** — MCP `shadcn:search_items_in_registries` or `shadcn search`.
4. **Get docs and examples** — run `shadcn docs <component>` to get URLs, then fetch them. Alternatively use MCP `shadcn:view_items_in_registries` or `shadcn view`.
5. **Install** — MCP `shadcn:get_add_command_for_items` or `shadcn add`.
4. **Get docs and examples** — run `shadcn docs <component>` to get URLs, then fetch them. Alternatively use MCP `shadcn:view_items_in_registries` or `shadcn view`. Note: `shadcn view` is for browsing registry items you haven't installed. To preview changes to installed components, use `shadcn add --diff`.
5. **Install or update** — MCP `shadcn:get_add_command_for_items` or `shadcn add`. When updating existing components, use `--dry-run` and `--diff` to preview changes first (see [Updating Components](#updating-components) below).
6. **Fix imports in third-party components** — After adding components from community registries (e.g. `@bundui`, `@magicui`), check the added non-UI files for hardcoded import paths like `@/components/ui/...`. These won't match the project's actual aliases. Use `shadcn info` to get the correct `ui` alias (e.g. `@workspace/ui/components`) and rewrite the imports accordingly. The CLI rewrites imports for its own UI files, but third-party registry components may use default paths that don't match the project.
7. **Verify** — MCP `shadcn:get_audit_checklist`.
8. **Switching presets** — Before running `shadcn init --preset <code>` in an existing project, always ask the user if they'd like to reinstall existing UI components. If yes, use the `--reinstall` flag to overwrite them with the new preset styles.
If MCP is unavailable, use CLI: `shadcn search`, `shadcn view`, `shadcn add`.
## Updating Components
When the user asks to update a component from upstream while keeping their local changes, use `--dry-run` and `--diff` to intelligently merge. **NEVER fetch raw files from GitHub manually — always use the CLI.**
1. Run `shadcn add <component> --dry-run` to see all files that would be affected.
2. For each file, run `shadcn add <component> --diff <file>` to see what changed upstream vs local.
3. Decide per file based on the diff:
- No local changes → safe to overwrite.
- Has local changes → read the local file, analyze the diff, and apply upstream updates while preserving local modifications.
- User says "just update everything" → use `--overwrite`, but confirm first.
4. **Never use `--overwrite` without the user's explicit approval.**
## Quick Reference
```bash
@@ -104,6 +115,11 @@ shadcn add button card dialog
shadcn add @magicui/shimmer-button
shadcn add --all
# Preview changes before adding/updating.
shadcn add button --dry-run
shadcn add button --diff button.tsx
shadcn add button --view button.tsx
# Search registries.
shadcn search @shadcn -q "sidebar"
shadcn search @blocks -q "stats"
@@ -111,7 +127,7 @@ shadcn search @blocks -q "stats"
# Get component docs and example URLs.
shadcn docs button dialog select
# View item details.
# View registry item details (for items not yet installed).
shadcn view @shadcn/button
```

View File

@@ -4,6 +4,13 @@ All commands use `shadcn <command>`. Configuration is read from `components.json
> **IMPORTANT:** Always use the `shadcn` command directly. Never prefix with `npx`, `pnpm dlx`, or any package runner.
## Contents
- Commands: init, add (dry-run, smart merge), search, view, docs, diff, info, build
- Templates: next, vite, start, react-router, astro
- Presets: named, code, URL formats and fields
- Switching presets
---
## Commands
@@ -35,6 +42,8 @@ Initializes shadcn/ui in an existing project or creates a new project (when `--n
### `add` — Add components
> **IMPORTANT:** To compare local components against upstream or to preview changes, ALWAYS use `shadcn add <component> --dry-run`, `--diff`, or `--view`. NEVER fetch raw files from GitHub or other sources manually. The CLI handles registry resolution, file paths, and CSS diffing automatically.
```bash
shadcn add [components...] [options]
```
@@ -49,6 +58,43 @@ Accepts component names, registry-prefixed names (`@magicui/shimmer-button`), UR
| `--all` | `-a` | Add all available components | `false` |
| `--path <path>` | `-p` | Target path for the component | — |
| `--silent` | `-s` | Mute output | `false` |
| `--dry-run` | | Preview all changes without writing files | `false` |
| `--diff <path>` | | Show the diff for a specific file (implies `--dry-run`) | — |
| `--view <path>` | | Show the full content of a specific file (implies `--dry-run`) | — |
#### Dry-Run Mode
Use `--dry-run` to preview what `add` would do without writing any files. `--diff` and `--view` both imply `--dry-run`.
```bash
# Preview all changes.
shadcn add button --dry-run
# Show the diff for a specific file.
shadcn add button --diff button.tsx
# Show the full content of a specific file.
shadcn add button --view button.tsx
# Works with URLs too.
shadcn add https://api.npoint.io/abc123 --dry-run
# CSS diffs.
shadcn add button --diff globals.css
```
**When to use dry-run:**
- When the user asks "what files will this add?" or "what will this change?" — use `--dry-run`.
- Before overwriting existing components — use `--diff` to preview the changes first.
- When the user wants to inspect component source code without installing — use `--view`.
- When checking what CSS changes would be made to `globals.css` — use `--diff globals.css`.
> **`shadcn add --dry-run` vs `shadcn view`:** Prefer `shadcn add --dry-run/--diff/--view` over `shadcn view` when the user wants to preview changes to their project. `shadcn view` only shows raw registry metadata. `shadcn add --dry-run` shows exactly what would happen in the user's project: resolved file paths, diffs against existing files, and CSS updates. Use `shadcn view` only when the user wants to browse registry info without a project context.
#### Smart Merge from Upstream
See [Updating Components in SKILL.md](./SKILL.md#updating-components) for the full workflow.
### `search` — Search registries

View File

@@ -2,6 +2,17 @@
Components reference semantic CSS variable tokens. Change the variables to change every component.
## Contents
- How it works (CSS variables → Tailwind utilities → components)
- Color variables and OKLCH format
- Dark mode setup
- Changing the theme (presets, CSS variables)
- Adding custom colors (Tailwind v3 and v4)
- Border radius
- Customizing components (variants, className, wrappers)
- Checking for updates
---
## How It Works
@@ -178,3 +189,12 @@ export function ConfirmDialog({ title, description, onConfirm, children }) {
shadcn diff # all components with available updates
shadcn diff button # specific component
```
To preview exactly what would change before updating, use `--dry-run` and `--diff`:
```bash
shadcn add button --dry-run # see all affected files
shadcn add button --diff button.tsx # see the diff for a specific file
```
See [Updating Components in SKILL.md](./SKILL.md#updating-components) for the full smart merge workflow.

View File

@@ -4,6 +4,17 @@ Rules and examples for composing shadcn/ui components.
> **Note:** Examples below use `@/` as the import prefix. Always use the actual `aliasPrefix` from `shadcn info` for the target project. Similarly, icon imports depend on the project's `iconLibrary` — use `lucide-react` for `lucide`, `@tabler/icons-react` for `tabler`, `@phosphor-icons/react` for `phosphor`, etc. Never assume `lucide-react`.
## Contents
- Component selection table
- Forms (FieldGroup, Field, form controls)
- Toggle groups
- Alerts
- Overlays
- Empty states
- Toast notifications
- Base-specific patterns
---
## Component Selection
@@ -190,41 +201,129 @@ toast("File deleted.", {
})
```
---
## Composition Rules
## Base-Specific Patterns
1. **Use `asChild` (radix) or `render` (base) for custom triggers.** Don't wrap triggers in extra elements. Check the `base` field from `shadcn info` to determine which prop to use.
Check the `base` field from `shadcn info` to determine which patterns to use.
2. **Use `Field` components for forms, not raw divs.** Never use `div` with `space-y-*` or `grid gap-*` for form layout. Use `FieldGroup` for the form container and `Field` for each control. Use `FieldLabel` for labelled inputs, `FieldTitle` for headings, `FieldDescription` for helper text.
### Composition: asChild (radix) vs render (base)
3. **Use existing UI components before custom markup.** Before writing a styled `div`, check if a component already exists: `Alert` for callouts, `ToggleGroup` for option sets, `Empty` for empty states, etc.
Radix uses `asChild` to replace the default element. Base UI uses `render` instead.
4. **Use `className` for layout, not styling.** Add layout utilities (`w-full`, `grid`, `flex`, `gap-*`) but avoid overriding component colors or typography.
```tsx
// radix.
<DialogTrigger asChild>
<Button>Open</Button>
</DialogTrigger>
5. **Prefer built-in variants.** Use `variant="outline"`, `variant="ghost"`, `size="sm"` etc. before adding custom classes.
// base.
<DialogTrigger render={<Button />}>Open</DialogTrigger>
```
6. **Compose, don't customize.** Build complex UIs by composing multiple simple components rather than heavily customizing a single one.
```tsx
// radix.
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon">Menu</Button>
</DropdownMenuTrigger>
7. **Add `"use client"` at RSC boundaries.** When `isRSC` is `true` (from `shadcn info`), components that use `useState`, `useEffect`, event handlers (`onClick`, `onChange`, etc.), or browser APIs must start with `"use client"`. Keep client boundaries as low in the tree as possible.
// base.
<DropdownMenuTrigger render={<Button variant="ghost" size="icon" />}>
Menu
</DropdownMenuTrigger>
```
8. **Keep components small and focused.** A component should render itself and its own interactions (e.g. a card + its dialog). Page-level layout, data arrays, and loops belong in the page, not the component.
### Button as a link (base only)
9. **Pass data directly, not keys.** When passing icons or other references through props, pass the actual objects (e.g. `icon={ComputerTerminal01Icon}`), not string keys to a lookup map.
When `render` changes a `Button` to a non-button element (`<a>`, `<span>`), add `nativeButton={false}` so Base UI doesn't apply button-specific behavior.
10. **Always wrap items and labels in a Group.** For menu-like components, items, labels, and subs must be direct children of their group component. Never place them directly inside the content container.
- `DropdownMenuItem`, `DropdownMenuLabel`, `DropdownMenuSub` → inside `DropdownMenuGroup`
- `MenubarItem`, `MenubarLabel`, `MenubarSub` → inside `MenubarGroup`
- `ContextMenuItem`, `ContextMenuLabel`, `ContextMenuSub` → inside `ContextMenuGroup`
- `SelectItem`, `SelectLabel` → inside `SelectGroup`
- `CommandItem` → inside `CommandGroup`
```tsx
// base.
<Button render={<a href="/docs" />} nativeButton={false}>
Read the docs
</Button>
11. **Always use `data-icon` on icons inside buttons.** When placing an icon inside a `Button`, add `data-icon="inline-start"` for prefix icons or `data-icon="inline-end"` for suffix icons. This ensures correct spacing. Never add sizing classes to the icon — the button handles sizing automatically.
// radix equivalent.
<Button asChild>
<a href="/docs">Read the docs</a>
</Button>
```
12. **Always use `InputGroupInput` and `InputGroupTextarea` inside an `InputGroup`.** Never use the base `Input` or `Textarea` components directly inside an `InputGroup`. The input-group variants reset borders, backgrounds, and focus rings to compose correctly within the group.
### Non-button trigger elements (base only)
13. **Buttons inside inputs use `InputGroup` + `InputGroupAddon`.** Never place a `Button` directly inside or adjacent to an `Input` with custom positioning. Wrap in `InputGroup` and use `InputGroupAddon` for the button.
When a trigger's `render` is not a `Button` (e.g. `InputGroupAddon`), add `nativeButton={false}`.
14. **`InputGroupAddon` must use `InputGroupButton`.** Never place a raw `Button` inside `InputGroupAddon`. Always use `InputGroupButton` instead.
```tsx
// base.
<PopoverTrigger render={<InputGroupAddon />} nativeButton={false}>
Pick date
</PopoverTrigger>
```
15. **`InputGroupButton` sizing depends on addon alignment.** When `InputGroupAddon` is `align="inline-start"` or `align="inline-end"`, prefer `size="icon-sm"` or `size="icon-xs"` (icon-only buttons). When `align="block-start"` or `align="block-end"`, prefer `size="xs"` or `size="sm"` (buttons with text).
### Select: items prop (base only)
Base `Select` requires an `items` prop on the root. It also supports `multiple` and `itemToStringValue` props.
```tsx
// base.
const items = ["Admin", "Member", "Viewer"]
<Select items={items}>
<SelectTrigger>
<SelectValue placeholder="Choose a role" />
</SelectTrigger>
<SelectContent>
{items.map((item) => (
<SelectItem key={item} value={item}>{item}</SelectItem>
))}
</SelectContent>
</Select>
```
Radix `Select` uses JSX only — no `items` prop. Use `placeholder` on `SelectValue`.
```tsx
// radix.
<Select>
<SelectTrigger>
<SelectValue placeholder="Choose a role" />
</SelectTrigger>
<SelectContent>
<SelectItem value="admin">Admin</SelectItem>
<SelectItem value="member">Member</SelectItem>
<SelectItem value="viewer">Viewer</SelectItem>
</SelectContent>
</Select>
```
### Accordion: type prop (radix only)
Radix requires `type="single"` or `type="multiple"` and supports `collapsible`. The `defaultValue` is a string.
```tsx
// radix.
<Accordion type="single" collapsible defaultValue="item-1">
<AccordionItem value="item-1">...</AccordionItem>
</Accordion>
```
Base uses no `type` prop. Use the `multiple` prop for multi-select. The `defaultValue` is an array.
```tsx
// base.
<Accordion defaultValue={["item-1"]}>
<AccordionItem value="item-1">...</AccordionItem>
</Accordion>
// base multi-select.
<Accordion multiple defaultValue={["item-1", "item-2"]}>
<AccordionItem value="item-1">...</AccordionItem>
<AccordionItem value="item-2">...</AccordionItem>
</Accordion>
```
---
For composition rules (asChild/render, className usage, Groups, data-icon, InputGroup, etc.), see the **Critical Rules** section in [SKILL.md](./SKILL.md#critical-rules).

View File

@@ -2,6 +2,20 @@
Build and publish your own shadcn/ui-compatible component registry. Registries let you distribute reusable components, blocks, hooks, and utilities that others can install with a single command.
## Contents
- Overview and directory structure
- registry.json format (required fields, item fields)
- Item types (registry:ui, registry:block, registry:hook, etc.)
- File objects and target paths
- Dependencies (NPM and registry)
- CSS variables and CSS rules
- Environment variables
- Building and hosting
- User configuration (simple, authenticated)
- Community registry index
- Examples (minimal registry, multi-file block)
---
## Overview