From acd2b21597f4673f754c72df7d01bd6a5a467e8e Mon Sep 17 00:00:00 2001 From: Zhongwei Li Date: Sun, 30 Nov 2025 09:01:28 +0800 Subject: [PATCH] Initial commit --- .claude-plugin/plugin.json | 12 + README.md | 3 + plugin.lock.json | 52 ++ skills/skill/SKILL.md | 490 +++++++++++++++ skills/skill/references/components.md | 830 ++++++++++++++++++++++++++ skills/skill/references/theming.md | 342 +++++++++++ 6 files changed, 1729 insertions(+) create mode 100644 .claude-plugin/plugin.json create mode 100644 README.md create mode 100644 plugin.lock.json create mode 100644 skills/skill/SKILL.md create mode 100644 skills/skill/references/components.md create mode 100644 skills/skill/references/theming.md diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..429f5bc --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,12 @@ +{ + "name": "styling-with-tailwind", + "description": "Skill: Build beautiful UIs with Tailwind CSS and shadcn/ui - modern utility-first styling, component patterns, and Tailwind v4.1 features", + "version": "0.0.0-2025.11.28", + "author": { + "name": "Misha Kolesnik", + "email": "misha@kolesnik.io" + }, + "skills": [ + "./skills/skill" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..2c3ef96 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# styling-with-tailwind + +Skill: Build beautiful UIs with Tailwind CSS and shadcn/ui - modern utility-first styling, component patterns, and Tailwind v4.1 features diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..e68257c --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,52 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:tenequm/claude-plugins:styling-with-tailwind", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "437c88f75d31b608740c5301d1d22e1ab46ecfef", + "treeHash": "67fae3511f3c99a6e7a3a601c981c3849ebc66663028634f497245569c8ce1c5", + "generatedAt": "2025-11-28T10:28:38.495771Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "styling-with-tailwind", + "description": "Skill: Build beautiful UIs with Tailwind CSS and shadcn/ui - modern utility-first styling, component patterns, and Tailwind v4.1 features" + }, + "content": { + "files": [ + { + "path": "README.md", + "sha256": "d887c0c4c600fa0a052a91981a766e83077403324aa57e012a84165a5c2e727d" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "19b9bee645a9b4dbd195f88d89f081547a22825033975bc09f418684525c4c13" + }, + { + "path": "skills/skill/SKILL.md", + "sha256": "b0a2d7183f0486103ce0071dedc1ece396b07591a5edf18ceed5e4461c375128" + }, + { + "path": "skills/skill/references/components.md", + "sha256": "c42d361b5d7cf0d66c67be567e1003565d291c9daa876e813014a1dc53ae0a2d" + }, + { + "path": "skills/skill/references/theming.md", + "sha256": "82d1d5f0b04c0ed992489e0ef4eb0f413a154c8cc61e897ce274a4d3d7d10c31" + } + ], + "dirSha256": "67fae3511f3c99a6e7a3a601c981c3849ebc66663028634f497245569c8ce1c5" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file diff --git a/skills/skill/SKILL.md b/skills/skill/SKILL.md new file mode 100644 index 0000000..7909399 --- /dev/null +++ b/skills/skill/SKILL.md @@ -0,0 +1,490 @@ +--- +name: styling-with-tailwind +description: Creates UIs using Tailwind CSS utility classes and shadcn/ui patterns. Covers CSS variables with OKLCH colors, component variants with CVA, responsive design, dark mode, and Tailwind v4 features. Use when building interfaces with Tailwind, styling shadcn/ui components, implementing themes, or working with utility-first CSS. +--- + +# Styling with Tailwind CSS + +Build accessible UIs using Tailwind utility classes and shadcn/ui component patterns. + +## Core Patterns + +### CSS Variables for Theming + +shadcn/ui uses semantic CSS variables mapped to Tailwind utilities: + +```css +/* globals.css - Light mode */ +:root { + --background: oklch(1 0 0); + --foreground: oklch(0.145 0 0); + --primary: oklch(0.205 0 0); + --primary-foreground: oklch(0.985 0 0); + --muted: oklch(0.97 0 0); + --muted-foreground: oklch(0.556 0 0); + --border: oklch(0.922 0 0); + --radius: 0.5rem; +} + +/* Dark mode */ +.dark { + --background: oklch(0.145 0 0); + --foreground: oklch(0.985 0 0); + --primary: oklch(0.922 0 0); + --primary-foreground: oklch(0.205 0 0); +} + +/* Tailwind v4: Map variables */ +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-primary: var(--primary); +} +``` + +**Usage in components:** +```tsx +// Background colors omit the "-background" suffix +
+
+
+``` + +### Component Variants with CVA + +Use `class-variance-authority` for component variants: + +```tsx +import { cva } from "class-variance-authority" + +const buttonVariants = cva( + "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground shadow hover:bg-primary/90", + destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: "border border-input bg-background hover:bg-accent", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-9 px-4 py-2", + sm: "h-8 px-3 text-xs", + lg: "h-10 px-8", + icon: "size-9", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +// Usage + +``` + +### Responsive Design + +Mobile-first breakpoints: + +```tsx +// Stack on mobile, grid on tablet+ +
+ +// Hide on mobile +
+ +// Different layouts per breakpoint +
+
+ +// Responsive text sizes +

+``` + +### Dark Mode + +```tsx +// Use dark: prefix for dark mode styles +
+ +// Theme toggle component +"use client" +import { Moon, Sun } from "lucide-react" +import { useTheme } from "next-themes" + +export function ThemeToggle() { + const { theme, setTheme } = useTheme() + + return ( + + ) +} +``` + +## Common Component Patterns + +### Card + +```tsx +
+
+

Title

+

Description

+
+
Content
+
Footer
+
+``` + +### Form Field + +```tsx +
+ + +

Helper text

+
+``` + +### Badge + +```tsx +const badgeVariants = cva( + "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors", + { + variants: { + variant: { + default: "border-transparent bg-primary text-primary-foreground shadow", + secondary: "border-transparent bg-secondary text-secondary-foreground", + destructive: "border-transparent bg-destructive text-destructive-foreground", + outline: "text-foreground", + }, + }, + } +) +``` + +### Alert + +```tsx +
+ +
Alert Title
+
Description
+
+``` + +### Loading Skeleton + +```tsx +
+
+
+
+``` + +## Layout Patterns + +### Centered Layout + +```tsx +
+
+ {/* Content */} +
+
+``` + +### Sidebar Layout + +```tsx +
+ +
Content
+
+``` + +### Dashboard Grid + +```tsx +
+ Wide card + Regular + Regular + Full width +
+``` + +### Container with Max Width + +```tsx +
+
+ {/* Centered content */} +
+
+``` + +## Accessibility Patterns + +### Focus Visible + +```tsx + +``` + +**Overflow Wrap:** +```tsx +// Break long words +

+ verylongwordthatneedstowrap +

+ +

+ URLs and long strings +

+``` + +## OKLCH Colors + +Use OKLCH for better color perception: + +```css +/* Format: oklch(lightness chroma hue) */ +--primary: oklch(0.205 0 0); +--destructive: oklch(0.577 0.245 27.325); + +/* Benefits: perceptually uniform, consistent lightness across hues */ +``` + +## Base Color Palettes + +shadcn/ui provides multiple base colors: + +```css +/* Neutral (default) - pure grayscale */ +--primary: oklch(0.205 0 0); + +/* Zinc - cooler, blue-gray */ +--primary: oklch(0.21 0.006 285.885); + +/* Slate - balanced blue-gray */ +--primary: oklch(0.208 0.042 265.755); + +/* Stone - warmer, brown-gray */ +--primary: oklch(0.216 0.006 56.043); +``` + +## Best Practices + +### Prefer Semantic Colors + +```tsx +// Good - uses theme +
+ +// Avoid - hardcoded +
+``` + +### Group Related Utilities + +```tsx +
+``` + +### Avoid Arbitrary Values + +```tsx +// Prefer design tokens +
+ +// Avoid when unnecessary +
+``` + +## Installation + +```bash +# Initialize shadcn/ui +pnpm dlx shadcn@latest init + +# Add components +pnpm dlx shadcn@latest add button card form + +# Add all components +pnpm dlx shadcn@latest add --all +``` + +## Troubleshooting + +**Colors not updating:** +1. Check CSS variable in globals.css +2. Verify @theme inline includes variable +3. Clear build cache + +**Dark mode not working:** +1. Verify ThemeProvider wraps app +2. Check suppressHydrationWarning on html tag +3. Ensure dark: variants defined + +**Tailwind v4 migration:** +1. Run `@tailwindcss/upgrade@next` codemod +2. Update CSS variables with hsl() wrappers +3. Change @theme to @theme inline +4. Install tw-animate-css + +## Component Patterns + +For detailed component patterns see [components.md](components.md): +- **Composition**: asChild pattern for wrapping elements +- **Typography**: Heading scales, prose styles, inline code +- **Forms**: React Hook Form with Zod validation +- **Icons**: Lucide icons integration and sizing +- **Inputs**: OTP, file, grouped inputs +- **Dialogs**: Modal patterns and composition +- **Data Tables**: TanStack table integration +- **Toasts**: Sonner notifications +- **CLI**: Complete command reference + +## Resources + +See [theming.md](theming.md) for complete color system reference and examples. + +## Summary + +Key concepts: +- Use semantic CSS variables for theming +- Apply CVA for component variants +- Follow mobile-first responsive patterns +- Implement dark mode with next-themes +- Use OKLCH for modern color handling +- Prefer Tailwind v4 features (size-*, @theme) +- Always ensure accessibility with focus-visible, sr-only + +This skill focuses on shadcn/ui patterns with Tailwind CSS. For component-specific examples, refer to the official shadcn/ui documentation. diff --git a/skills/skill/references/components.md b/skills/skill/references/components.md new file mode 100644 index 0000000..31aefbe --- /dev/null +++ b/skills/skill/references/components.md @@ -0,0 +1,830 @@ +# Component Patterns Reference + +## Composition with asChild + +Use `asChild` to compose components without wrapper divs: + +```tsx +// Button as a Link (Next.js) +import Link from "next/link" + + + +// Renders: Login +// No wrapper div! + +// Button as a custom component + + +// Dialog trigger with custom element + +
+ Custom trigger element +
+
+``` + +**When to use:** +- Wrapping navigation links +- Custom interactive elements +- Avoiding nested buttons +- Semantic HTML (button → link when navigating) + +## Typography Patterns + +shadcn/ui typography scales using Tailwind utilities: + +```tsx +// Headings with responsive sizing +

+ Taxing Laughter: The Joke Tax Chronicles +

+ +

+ The People of the Kingdom +

+ +

+ The Joke Tax +

+ +

+ People stopped telling jokes +

+ +// Paragraph +

+ The king, seeing how much happier his subjects were, realized the error of his ways. +

+ +// Blockquote +
+ "After all," he said, "everyone enjoys a good joke." +
+ +// Inline code + + @radix-ui/react-alert-dialog + + +// Lead text (larger paragraph) +

+ A modal dialog that interrupts the user with important content. +

+ +// Small text +Email address + +// Muted text +

+ Enter your email address. +

+ +// List +
    +
  • 1st level of puns: 5 gold coins
  • +
  • 2nd level of jokes: 10 gold coins
  • +
  • 3rd level of one-liners: 20 gold coins
  • +
+``` + +## Icons with Lucide + +```tsx +import { ChevronRight, Check, X, AlertCircle, Loader2 } from "lucide-react" + +// Icon sizing with components + + +// Icons automatically adjust to button size + + + + +// Icon-only button + + +// Loading state + + +// Icon with semantic colors + + + +// In alerts + + + Error + + Your session has expired. + + +``` + +**Icon sizing reference:** +- `size-3` - Extra small (12px) +- `size-4` - Small/default (16px) +- `size-5` - Medium (20px) +- `size-6` - Large (24px) + +## Form with React Hook Form + +Complete form example with validation: + +```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 { toast } from "sonner" + +// Define schema +const formSchema = z.object({ + username: z.string().min(2, { + message: "Username must be at least 2 characters.", + }), + email: z.string().email({ + message: "Please enter a valid email address.", + }), + bio: z.string().max(160).min(4), +}) + +export function ProfileForm() { + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: { + username: "", + email: "", + bio: "", + }, + }) + + function onSubmit(values: z.infer) { + toast.success("Profile updated successfully") + console.log(values) + } + + return ( +
+ + ( + + Username + + + + + This is your public display name. + + + + )} + /> + + ( + + Email + + + + + + )} + /> + + ( + + Bio + +