Svelte 5 Showcase Components
Quick Start
The Svelte 5 Showcase is a production-ready component library with 49 components organized into 7 categories, built with Svelte 5 runes, TypeScript strict mode, and TailwindCSS v4.
Showcase Location: /Users/dawiddutoit/projects/play/svelte
Component Categories:
- Primitives (24) - Core UI primitives (buttons, inputs, forms, dialogs)
- Navigation (6) - Navigation patterns (tabs, breadcrumbs, pagination, menus)
- Data Display (6) - Display components (tables, accordions, avatars, carousels)
- Overlays (5) - Modal dialogs and overlays (popovers, sheets, drawers)
- Feedback (2) - User feedback (progress bars, toast notifications)
- Layout (2) - Layout primitives (aspect ratio, resizable panels)
- Custom (4) - Brand-specific components (hero sections, service cards)
Quick Component Lookup:
# Browse all components at:
/Users/dawiddutoit/projects/play/svelte/src/lib/components/ui/
# Example showcase pages:
/Users/dawiddutoit/projects/play/svelte/src/routes/showcase/primitives/button/+page.svelte
/Users/dawiddutoit/projects/play/svelte/src/routes/showcase/primitives/form/+page.svelte
Table of Contents
- When to Use This Skill
- Component Inventory
- Quick Integration
- Common Usage Patterns
- Form Handling
- Supporting Files
- Expected Outcomes
- Requirements
- Red Flags to Avoid
When to Use This Skill
Explicit Triggers
Invoke this skill when the user explicitly asks for:
- "What components are available in the showcase?"
- "How do I use the [component name] component?"
- "Show me examples of [component type]"
- "How to integrate showcase components into my project?"
- "Copy [component] from showcase to my project"
- "What's the difference between Dialog and Drawer?"
- "Showcase component documentation"
Implicit Triggers
Invoke when the user's task involves:
- Building UI with Svelte 5 and needs component references
- Looking for form validation examples with sveltekit-superforms
- Needing accessible component patterns
- Asking about Svelte 5 runes usage in components
- Requesting Tailwind CSS component styling patterns
- Exploring shadcn-svelte implementation examples
Debugging Triggers
Invoke when troubleshooting:
- Import errors with showcase components
- Svelte 5 runes syntax issues in components
- Form validation not working with superforms
- Tailwind classes not applying to components
- TypeScript errors in component props
- Component styling inconsistencies
Component Inventory
Complete Component List (49 Total)
Primitives (24 components)
Form Controls:
Button- Clickable button with variants (default, destructive, outline, ghost, link)Input- Text input field with type variantsTextarea- Multi-line text inputCheckbox- Boolean checkbox with labelSwitch- Toggle switch componentRadio Group- Radio button groupSelect- Dropdown selection menuSlider- Range slider inputLabel- Accessible form labelInput OTP- One-time password input
Form Components:
Form Field- Form field wrapper with contextForm Label- Accessible form labelForm Description- Helper text for fieldsForm Field Errors- Validation error displayForm Fieldset- Group related fieldsForm Button- Form submit button
Feedback & Display:
Alert- Alert messages with variantsAlert Dialog- Modal confirmation dialogBadge- Status badge with variantsCard- Container card with header/footerDialog- Modal dialog overlaySkeleton- Loading skeleton placeholderTooltip- Hover tooltipToggle- Toggle buttonToggle Group- Toggle button group
Date Inputs:
Calendar- Date picker calendarRange Calendar- Date range picker
Navigation (6 components)
Breadcrumb- Breadcrumb navigation trailCommand- Command palette / searchMenubar- Menu bar navigationNavigation Menu- Dropdown navigation menuPagination- Page navigationTabs- Tabbed interface
Data Display (6 components)
Accordion- Collapsible content sectionsAvatar- User avatar with fallbackCarousel- Image/content carousel (Embla)Collapsible- Single collapsible sectionScroll Area- Custom scrollbar areaTable- Data table with header/footer
Overlays (5 components)
Context Menu- Right-click context menuDrawer- Bottom drawer overlay (Vaul)Hover Card- Hover card overlayPopover- Popover overlaySheet- Side sheet overlay
Feedback (2 components)
Progress- Progress bar indicatorSonner- Toast notification system
Layout (2 components)
Aspect Ratio- Aspect ratio containerResizable- Resizable panel layout (Paneforge)
Custom Components (4 components)
Feature Card- Branded feature cardHero Section- Landing page heroLoading Spinner- Custom loading animationService Card- Expandable service card with credentials
Location: /Users/dawiddutoit/projects/play/svelte/src/lib/components/ui/
Quick Integration
Method 1: Using shadcn-svelte CLI (Recommended)
# Install CLI and add components
npx shadcn-svelte@latest add button
npx shadcn-svelte@latest add card
npx shadcn-svelte@latest add form
What this does:
- Installs required dependencies
- Copies component files to
src/lib/components/ui/ - Updates barrel exports in
index.ts
Method 2: Manual Copy from Showcase
Step 1: Copy component directory
# Copy button component
cp -r /Users/dawiddutoit/projects/play/svelte/src/lib/components/ui/button \
./src/lib/components/ui/
# Copy multiple components
cp -r /Users/dawiddutoit/projects/play/svelte/src/lib/components/ui/{button,card,input} \
./src/lib/components/ui/
Step 2: Update barrel exports
// src/lib/components/index.ts
export { Button, buttonVariants } from './ui/button';
export { Card, CardHeader, CardTitle, CardContent, CardFooter } from './ui/card';
export { Input } from './ui/input';
Step 3: Install dependencies
npm install bits-ui clsx tailwind-merge tailwind-variants lucide-svelte
Step 4: Copy utilities
// src/lib/utils.ts
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
export type WithElementRef<T, U extends HTMLElement = HTMLElement> = T & { ref?: U | null };
Method 3: Read from Showcase
<script lang="ts">
// Read showcase implementation for reference
// Location: /Users/dawiddutoit/projects/play/svelte/src/lib/components/ui/[component]/
</script>
View showcase examples:
/Users/dawiddutoit/projects/play/svelte/src/routes/showcase/primitives/[component]/+page.svelte
Common Usage Patterns
Svelte 5 Runes (Required Syntax)
All components use Svelte 5 runes:
<script lang="ts">
// ✅ Svelte 5 (REQUIRED)
let count = $state(0);
let doubled = $derived(count * 2);
$effect(() => {
console.log('count changed:', count);
});
// ❌ Svelte 4 (DO NOT USE)
// let count = 0;
// $: doubled = count * 2;
// $: console.log(count);
</script>
Props Pattern
<script lang="ts">
interface Props {
title: string;
count?: number;
variant?: 'default' | 'destructive';
onUpdate?: (value: number) => void;
}
let { title, count = 0, variant = 'default', onUpdate }: Props = $props();
</script>
Bindable Props
<script lang="ts">
// Component with bindable value
interface Props {
value: string;
onChange?: (value: string) => void;
}
let { value = $bindable(), onChange }: Props = $props();
</script>
<input bind:value oninput={() => onChange?.(value)} />
<!-- Parent usage -->
<script lang="ts">
let searchQuery = $state('');
</script>
<MyComponent bind:value={searchQuery} />
Component Composition
<script lang="ts">
import { Card, CardHeader, CardTitle, CardContent, CardFooter } from '$lib/components';
import { Button } from '$lib/components';
</script>
<Card>
<CardHeader>
<CardTitle>Card Title</CardTitle>
</CardHeader>
<CardContent>
<p>Card content goes here</p>
</CardContent>
<CardFooter>
<Button>Action</Button>
</CardFooter>
</Card>
Tailwind Class Merging
<script lang="ts">
import { cn } from '$lib/utils';
interface Props {
class?: string;
}
let { class: className }: Props = $props();
</script>
<div class={cn('default-bg-white p-4 rounded', className)}>
Content
</div>
Icon Integration
<script lang="ts">
import { Button } from '$lib/components';
import { Mail, Loader2 } from 'lucide-svelte';
</script>
<Button>
<Mail class="mr-2 h-4 w-4" />
Login with Email
</Button>
<Button disabled>
<Loader2 class="mr-2 h-4 w-4 animate-spin" />
Please wait
</Button>
Form Handling
Complete Form Integration
1. Create Zod Schema:
// schema.ts
import { z } from 'zod';
export const contactSchema = z.object({
name: z.string().min(2, 'Name must be at least 2 characters'),
email: z.string().email('Invalid email address'),
message: z.string().min(10, 'Message must be at least 10 characters'),
newsletter: z.boolean().default(false)
});
export type ContactForm = z.infer<typeof contactSchema>;
2. Server-Side Validation:
// +page.server.ts
import type { PageServerLoad, Actions } from './$types';
import { superValidate } from 'sveltekit-superforms';
import { zod } from 'sveltekit-superforms/adapters';
import { contactSchema } from './schema';
import { fail } from '@sveltejs/kit';
export const load: PageServerLoad = async () => {
const form = await superValidate(zod(contactSchema));
return { form };
};
export const actions: Actions = {
default: async ({ request }) => {
const form = await superValidate(request, zod(contactSchema));
if (!form.valid) {
return fail(400, { form });
}
// Process form data
console.log('Form submitted:', form.data);
return { form };
}
};
3. Client-Side Component:
<!-- +page.svelte -->
<script lang="ts">
import { superForm } from 'sveltekit-superforms';
import { zodClient } from 'sveltekit-superforms/adapters';
import {
FormField,
FormLabel,
FormDescription,
FormFieldErrors,
Input,
Textarea,
Checkbox,
Button
} from '$lib/components';
import { contactSchema } from './schema';
import type { PageData } from './$types';
let { data }: { data: PageData } = $props();
const { form, errors, enhance, delayed } = superForm(data.form, {
validators: zodClient(contactSchema)
});
</script>
<form method="POST" use:enhance class="space-y-6 max-w-2xl">
<FormField name="name" {form}>
{#snippet children({ value })}
<FormLabel>Full Name</FormLabel>
<Input bind:value={$form.name} placeholder="John Doe" />
<FormFieldErrors />
{/snippet}
</FormField>
<FormField name="email" {form}>
{#snippet children({ value })}
<FormLabel>Email</FormLabel>
<FormDescription>We'll never share your email</FormDescription>
<Input type="email" bind:value={$form.email} placeholder="you@example.com" />
<FormFieldErrors />
{/snippet}
</FormField>
<FormField name="message" {form}>
{#snippet children({ value })}
<FormLabel>Message</FormLabel>
<Textarea bind:value={$form.message} rows={5} placeholder="Your message..." />
<FormFieldErrors />
{/snippet}
</FormField>
<FormField name="newsletter" {form}>
{#snippet children({ value })}
<div class="flex items-center space-x-2">
<Checkbox id="newsletter" bind:checked={$form.newsletter} />
<FormLabel for="newsletter">Subscribe to newsletter</FormLabel>
</div>
<FormFieldErrors />
{/snippet}
</FormField>
<Button type="submit" disabled={$delayed}>
{$delayed ? 'Submitting...' : 'Send Message'}
</Button>
</form>
Example Location: /Users/dawiddutoit/projects/play/svelte/src/routes/showcase/primitives/form/+page.svelte
Supporting Files
examples/component-examples.md
Comprehensive usage examples for all 49 components organized by category:
- Primitives - All 24 primitive components with props and usage
- Navigation - 6 navigation components with real-world examples
- Data Display - 6 display components with data binding patterns
- Overlays - 5 overlay components with trigger/content patterns
- Feedback - 2 feedback components with state management
- Layout - 2 layout components with responsive patterns
- Custom - 4 custom components with brand-specific examples
Use when: You need copy-paste-ready code examples for specific components.
references/integration-guide.md
Complete integration guide covering:
- Quick Setup - Install dependencies, configure Vite, create utilities
- Component Architecture - shadcn-svelte philosophy, structure patterns
- Required Dependencies - Complete dependency table with versions
- Configuration Files - TypeScript config, path aliases, Vite setup
- Copy/Paste Integration - Three methods for integrating components
- Common Patterns - Svelte 5 runes, props, bindable values, composition
- Form Integration - Complete form example with Zod + superforms
- Styling Customization - Variant customization, CSS variables, dark mode
- Troubleshooting - Common issues and solutions
Use when: You're setting up a new project or debugging integration issues.
Expected Outcomes
Successful Component Discovery
✅ Component Found
Component: Button
Category: Primitives
Location: /Users/dawiddutoit/projects/play/svelte/src/lib/components/ui/button/
Variants: default, destructive, outline, secondary, ghost, link
Sizes: sm, default, lg, icon, icon-sm, icon-lg
Dependencies:
- tailwind-variants (variants)
- lucide-svelte (icons, optional)
Example Location:
/Users/dawiddutoit/projects/play/svelte/src/routes/showcase/primitives/button/+page.svelte
Integration Command:
npx shadcn-svelte@latest add button
Successful Component Integration
✅ Component Integrated Successfully
Component: Button
Copied to: ./src/lib/components/ui/button/
Barrel export: Updated index.ts
Dependencies installed:
✓ tailwind-variants@^3.2.2
✓ clsx@^2.1.1
✓ tailwind-merge@^3.4.0
Next steps:
1. Import: import { Button } from '$lib/components';
2. Use: <Button>Click me</Button>
3. Customize variants as needed in button.svelte
Component ready to use!
Integration Failure
❌ Integration Failed
Component: Button
Error: Missing required dependencies
Missing packages:
- tailwind-variants
- clsx
- tailwind-merge
Fix:
npm install tailwind-variants clsx tailwind-merge
Also check:
1. Vite config has Tailwind plugin BEFORE SvelteKit
2. utils.ts exists with cn() function
3. TypeScript strict mode is enabled
Retry integration after installing dependencies.
Requirements
Environment
- Node.js: v18+ or v20+
- Package Manager: npm, pnpm, or yarn
- TypeScript: v5.x with strict mode
- Svelte: v5.2.0+
- SvelteKit: v2.9.0+
Core Dependencies
Framework:
svelte@^5.2.0- Svelte 5 with runes@sveltejs/kit@^2.9.0- SvelteKit frameworktypescript@^5.7.2- Type safety
UI Primitives:
bits-ui@^2.14.4- Headless componentslucide-svelte@^0.562.0- Icons
Styling:
@tailwindcss/vite@^4.0.0-beta.3- Tailwind CSS v4tailwindcss@^4.0.0-beta.3clsx@^2.1.1- Class utilitytailwind-merge@^3.4.0- Class mergingtailwind-variants@^3.2.2- Variants
Forms:
sveltekit-superforms@^2.29.1- Form handlingformsnap@^2.0.1- Form primitiveszod@^3.24.1- Validation
Configuration Files Required
- vite.config.ts - Tailwind plugin before SvelteKit
- src/lib/utils.ts - cn() utility function
- src/routes/+layout.svelte - Import Tailwind CSS
- tsconfig.json - Strict mode enabled
Knowledge Required
- Svelte 5 runes syntax ($state, $derived, $effect, $props)
- TypeScript interfaces and type inference
- Tailwind CSS utility classes
- Component composition patterns
- Form validation with Zod schemas
Red Flags to Avoid
❌ Using Svelte 4 Syntax
Never use Svelte 4 reactive declarations in Svelte 5 projects:
<!-- ❌ WRONG -->
<script>
let count = 0;
$: doubled = count * 2;
</script>
<!-- ✅ CORRECT -->
<script lang="ts">
let count = $state(0);
let doubled = $derived(count * 2);
</script>
❌ Wrong Vite Plugin Order
Tailwind MUST come before SvelteKit:
// ❌ WRONG
plugins: [sveltekit(), tailwindcss()]
// ✅ CORRECT
plugins: [tailwindcss(), sveltekit()]
❌ Disabling TypeScript Strict Mode
Components rely on strict type checking:
// ❌ WRONG
{ "strict": false }
// ✅ CORRECT
{ "strict": true }
❌ Using any Type
Never use any without justification:
// ❌ WRONG
let data: any = {};
// ✅ CORRECT
interface Data {
name: string;
count: number;
}
let data: Data = { name: 'test', count: 0 };
❌ Missing Form Adapters
Always use correct adapter for client/server:
// ❌ WRONG (server-side)
import { zodClient } from 'sveltekit-superforms/adapters';
await superValidate(request, zodClient(schema));
// ✅ CORRECT (server-side)
import { zod } from 'sveltekit-superforms/adapters';
await superValidate(request, zod(schema));
// ✅ CORRECT (client-side)
import { zodClient } from 'sveltekit-superforms/adapters';
superForm(data.form, { validators: zodClient(schema) });
❌ Installing Components via NPM
Components are copy/paste, not NPM packages:
# ❌ WRONG
npm install @shadcn-svelte/button
# ✅ CORRECT
npx shadcn-svelte@latest add button
❌ Using Inline Styles
Use Tailwind classes instead:
<!-- ❌ WRONG -->
<div style="background-color: #4f46e5; padding: 1rem;">Content</div>
<!-- ✅ CORRECT -->
<div class="bg-indigo-600 p-4">Content</div>
❌ Skipping Component Examples
Always check showcase examples before implementing:
✅ CORRECT Workflow:
1. Check /Users/dawiddutoit/projects/play/svelte/src/routes/showcase/[category]/[component]/+page.svelte
2. Read component implementation
3. Copy relevant patterns
4. Customize for your use case
❌ Mixing Component Libraries
Don't mix shadcn-svelte with other UI libraries:
<!-- ❌ WRONG -->
<script>
import { Button as ShadcnButton } from '$lib/components';
import { Button as MaterialButton } from '@material/svelte';
</script>
<!-- ✅ CORRECT -->
<script>
import { Button } from '$lib/components';
</script>
❌ Not Using Barrel Exports
Always export components through index.ts:
// ❌ WRONG
import { Button } from '$lib/components/ui/button/button.svelte';
// ✅ CORRECT
import { Button } from '$lib/components';
Notes
- Showcase is a reference, not a package - Copy components into your project
- All components use Svelte 5 runes - No Svelte 4 syntax allowed
- TypeScript strict mode required - Components rely on type safety
- Tailwind CSS is mandatory - Components are styled with Tailwind
- shadcn-svelte philosophy - Own the code, customize freely
- Examples are production-ready - Copy/paste and customize as needed
- Form handling uses superforms - Best-in-class validation and DX
- Icons use lucide-svelte - 1,666 icons, tree-shakeable
- Dark mode supported - Use mode-watcher for automatic theming
- Accessibility built-in - Components follow WAI-ARIA patterns