Skip to content
composable-svelte-components logo

Composable Svelte Components

composable-svelte-components

UI component library reference for Composable Svelte. Use when implementing designs, choosing components, styling layouts, or working with shadcn-svelte components. Covers component props, variants, accessibility patterns, visual composition, and when to use which component. For specialized compo...

SKILL.md

Full skill instructions

Composable Svelte Components

This skill covers the UI component library for Composable Svelte applications, focusing on shadcn-svelte components and integration patterns.

For Specialized Components: See dedicated skills for graphics (3D), code (editors/​media), charts (data viz), and maps (geospatial).


COMPONENT LIBRARY OVERVIEW

Composable Svelte includes 73+ shadcn-svelte components for building modern UIs. All components integrate with the Composable Architecture via props and state management.

Integration Pattern:

  • Props for configuration (labels, variants, styles)
  • State from $store for reactive data
  • Dispatch actions for user interactions

Package Organization:

  • @composable-svelte/​core - UI components (this skill)
  • @composable-svelte/​graphics - 3D graphics (see composable-svelte-graphics skill)
  • @composable-svelte/​code - Code editors, media players (see composable-svelte-code skill)
  • @composable-svelte/​charts - Data visualization (see composable-svelte-charts skill)
  • @composable-svelte/​maps - Interactive maps (see composable-svelte-maps skill)

NAVIGATION COMPONENTS

Purpose: Overlay-based UI elements for state-driven navigation.

Integration Pattern: State-driven open/​close via store, dismiss via PresentationAction.

See composable-svelte-navigation skill for implementation details. This section provides REFERENCE only.

Modal

Full-screen overlay with backdrop, centered content.

When to use: Primary actions, form submissions, important warnings.

Props:

  • open: boolean - Whether modal is open
  • onOpenChange: (open: boolean) => void - Callback when open state changes
import { Modal } from '@composable-svelte/​core/​components';

{#if modalStore}
  <Modal
    open={true}
    onOpenChange={(open) => !open && modalStore.dismiss()}
  >
    <ModalContent store={modalStore} />
  </​Modal>
{/​if}

Sheet

Bottom drawer that slides up (mobile-first).

When to use: Mobile-first UIs, filters, settings panels.

Props:

  • open: boolean
  • onOpenChange: (open: boolean) => void

Drawer

Side panel that slides from left or right.

When to use: Navigation menus, sidebars, settings.

Props:

  • side: 'left' | 'right' - Which side to slide from
  • open: boolean
  • onOpenChange: (open: boolean) => void

Alert

Confirmation dialog, centered, smaller than Modal.

When to use: Destructive actions, confirmations, yes/​no decisions.

Props:

  • open: boolean
  • onOpenChange: (open: boolean) => void

Popover

Contextual menu positioned near trigger element.

When to use: Dropdown menus, tooltips, context menus.

Props:

  • open: boolean
  • onOpenChange: (open: boolean) => void

FORM COMPONENTS

Purpose: User input elements that integrate with Composable Architecture.

Integration Pattern: Value from $store.state, dispatch on change, validation state from store.

See composable-svelte-forms skill for full patterns.

Input

Text input field with variants.

Types: text, email, password, number, tel, url, search, date, time.

Props:

  • type: string - Input type
  • value: string - Current value
  • oninput: (e: Event) => void - Change handler
  • placeholder: string - Placeholder text
  • disabled: boolean - Disabled state
import { Input } from '@composable-svelte/​core/​components';

<Input
  type="text"
  value={$store.name}
  oninput={(e) => store.dispatch({ type: 'nameChanged', name: e.currentTarget.value })}
  placeholder="Enter name"
  disabled={$store.isSubmitting}
/>

{#if $store.nameError}
  <span class="error">{$store.nameError}</​span>
{/​if}

Select

Dropdown selector.

Props:

  • value: string - Selected value
  • onValueChange: (value: string) => void - Selection handler
import { Select, SelectTrigger, SelectContent, SelectItem } from '@composable-svelte/​core/​components';

<Select
  value={$store.category}
  onValueChange={(value) => store.dispatch({ type: 'categoryChanged', category: value })}
>
  <SelectTrigger>
    <SelectValue placeholder="Select category" />
  </​SelectTrigger>
  <SelectContent>
    <SelectItem value="electronics">Electronics</​SelectItem>
    <SelectItem value="clothing">Clothing</​SelectItem>
    <SelectItem value="food">Food</​SelectItem>
  </​SelectContent>
</​Select>

Checkbox

Boolean toggle with label.

Props:

  • checked: boolean - Checked state
  • onCheckedChange: (checked: boolean) => void - Toggle handler
import { Checkbox } from '@composable-svelte/​core/​components';

<Checkbox
  checked={$store.agreeToTerms}
  onCheckedChange={(checked) => store.dispatch({ type: 'toggleTerms', checked })}
>
  I agree to the terms and conditions
</​Checkbox>

RadioGroup

Mutually exclusive options.

Props:

  • value: string - Selected value
  • onValueChange: (value: string) => void - Selection handler
import { RadioGroup, RadioGroupItem } from '@composable-svelte/​core/​components';

<RadioGroup
  value={$store.plan}
  onValueChange={(value) => store.dispatch({ type: 'planChanged', plan: value })}
>
  <RadioGroupItem value="free">Free</​RadioGroupItem>
  <RadioGroupItem value="pro">Pro ($9/​mo)</​RadioGroupItem>
  <RadioGroupItem value="enterprise">Enterprise ($99/​mo)</​RadioGroupItem>
</​RadioGroup>

Switch

Toggle switch.

Props:

  • checked: boolean
  • onCheckedChange: (checked: boolean) => void

Textarea

Multi-line text input.

Props:

  • value: string
  • oninput: (e: Event) => void
  • rows: number - Number of visible rows
  • placeholder: string

Combobox

Autocomplete dropdown.

Props:

  • value: string - Selected value
  • options: Array<{ label: string; value: string }> - Available options
  • onValueChange: (value: string) => void - Selection handler
  • onSearchChange: (query: string) => void - Search handler

DATA DISPLAY COMPONENTS

Purpose: Display data from store.state, often derived/​computed.

Integration Pattern: Map from store.state arrays, use $derived for filtering/​sorting.

Table

Tabular data display with sorting/​filtering.

When to use: Lists of structured data, data grids.

import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell } from '@composable-svelte/​core/​components';

<Table>
  <TableHeader>
    <TableRow>
      <TableHead>Name</​TableHead>
      <TableHead>Email</​TableHead>
      <TableHead>Status</​TableHead>
    </​TableRow>
  </​TableHeader>
  <TableBody>
    {#each $store.users as user (user.id)}
      <TableRow>
        <TableCell>{user.name}</​TableCell>
        <TableCell>{user.email}</​TableCell>
        <TableCell>{user.status}</​TableCell>
      </​TableRow>
    {/​each}
  </​TableBody>
</​Table>

Card

Container for related content with header/​footer.

When to use: Product cards, user profiles, content previews.

import { Card, CardHeader, CardTitle, CardDescription, CardContent } from '@composable-svelte/​core/​components';

{#each $store.products as product (product.id)}
  <Card>
    <CardHeader>
      <CardTitle>{product.name}</​CardTitle>
      <CardDescription>{product.category}</​CardDescription>
    </​CardHeader>
    <CardContent>
      <p>${product.price}</​p>
      <Button onclick={() => store.dispatch({ type: 'addToCart', productId: product.id })}>
        Add to Cart
      </​Button>
    </​CardContent>
  </​Card>
{/​each}

Badge

Small label/​tag.

Variants: default, success, secondary, destructive, outline.

import { Badge } from '@composable-svelte/​core/​components';

<Badge variant={$store.status === 'active' ? 'success' : 'secondary'}>
  {$store.status}
</​Badge>

Avatar

User profile image with fallback.

import { Avatar, AvatarImage, AvatarFallback } from '@composable-svelte/​core/​components';

<Avatar>
  <AvatarImage src={$store.user?.avatarUrl} alt={$store.user?.name} />
  <AvatarFallback>{$store.user?.initials}</​AvatarFallback>
</​Avatar>

FEEDBACK COMPONENTS

Purpose: Communicate loading states, errors, and notifications.

Integration Pattern: Render based on loading/​error/​success state from store.

Toast

Temporary notification.

When to use: Success messages, errors, notifications.

import { toast } from '@composable-svelte/​core/​components';

// In reducer
case 'itemAdded':
  return [
    { ...state, items: [...state.items, action.item] },
    Effect.fireAndForget(async () => {
      toast.success('Item added successfully');
    })
  ];

case 'itemDeleteFailed':
  return [
    { ...state, error: action.error },
    Effect.fireAndForget(async () => {
      toast.error('Failed to delete item');
    })
  ];

Progress

Linear progress indicator.

When to use: Upload progress, loading progress.

import { Progress } from '@composable-svelte/​core/​components';

{#if $store.uploadProgress !== null}
  <Progress value={$store.uploadProgress} max={100} />
  <p>{$store.uploadProgress}% uploaded</​p>
{/​if}

Skeleton

Loading placeholder with shimmer effect.

When to use: Content placeholders during loading.

import { Skeleton } from '@composable-svelte/​core/​components';

{#if $store.isLoading}
  <Skeleton class="h-4 w-full mb-2" />
  <Skeleton class="h-4 w-3/​4 mb-2" />
  <Skeleton class="h-4 w-1/​2" />
{:else}
  <p>{$store.content}</​p>
{/​if}

Spinner

Loading spinner.

Props:

  • size: 'small' | 'medium' | 'large'
import { Spinner } from '@composable-svelte/​core/​components';

{#if $store.isLoading}
  <Spinner size="large" />
{/​if}

LAYOUT COMPONENTS

Purpose: Organize UI with expand/​collapse, tabs, resizable panels.

Integration Pattern: Expanded/​active state lives in store, dispatch on user interaction.

Accordion

Expandable/​collapsible sections.

When to use: FAQs, collapsible content sections.

import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@composable-svelte/​core/​components';

// State
interface FAQState {
  expandedItems: string[]; // Array of expanded item IDs
}

// Reducer
case 'toggleItem':
  return [
    {
      ...state,
      expandedItems: state.expandedItems.includes(action.itemId)
        ? state.expandedItems.filter(id => id !== action.itemId)
        : [...state.expandedItems, action.itemId]
    },
    Effect.none()
  ];

// Component
<Accordion>
  {#each $store.faqItems as item (item.id)}
    <AccordionItem value={item.id}>
      <AccordionTrigger
        onclick={() => store.dispatch({ type: 'toggleItem', itemId: item.id })}
        expanded={$store.expandedItems.includes(item.id)}
      >
        {item.question}
      </​AccordionTrigger>
      <AccordionContent>
        {item.answer}
      </​AccordionContent>
    </​AccordionItem>
  {/​each}
</​Accordion>

Tabs

Tab navigation.

When to use: Multiple views of related content.

import { Tabs, TabsList, TabsTrigger, TabsContent } from '@composable-svelte/​core/​components';

// State
interface DashboardState {
  activeTab: 'overview' | 'analytics' | 'reports';
}

// Component
<Tabs value={$store.activeTab} onValueChange={(tab) => store.dispatch({ type: 'tabChanged', tab })}>
  <TabsList>
    <TabsTrigger value="overview">Overview</​TabsTrigger>
    <TabsTrigger value="analytics">Analytics</​TabsTrigger>
    <TabsTrigger value="reports">Reports</​TabsTrigger>
  </​TabsList>
  <TabsContent value="overview">
    <OverviewPanel store={store} />
  </​TabsContent>
  <TabsContent value="analytics">
    <AnalyticsPanel store={store} />
  </​TabsContent>
  <TabsContent value="reports">
    <ReportsPanel store={store} />
  </​TabsContent>
</​Tabs>

Collapsible

Single collapsible section.

When to use: Sidebar toggles, advanced settings.

import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '@composable-svelte/​core/​components';

<Collapsible
  open={$store.sidebarExpanded}
  onOpenChange={(open) => store.dispatch({ type: 'toggleSidebar', open })}
>
  <CollapsibleTrigger>
    <Button>Toggle Sidebar</​Button>
  </​CollapsibleTrigger>
  <CollapsibleContent>
    <nav>
      <a href="/​dashboard">Dashboard</​a>
      <a href="/​settings">Settings</​a>
    </​nav>
  </​CollapsibleContent>
</​Collapsible>

SPECIALIZED COMPONENT PACKAGES

For specialized components beyond standard UI, see dedicated skills:

3D Graphics

Skill: composable-svelte-graphics Package: @composable-svelte/​graphics Components: Scene, Camera, Light, Mesh Use cases: 3D visualizations, WebGPU/​WebGL rendering, geometry (box, sphere, cylinder, torus, plane)

Code & Media

Skill: composable-svelte-code Package: @composable-svelte/​code Components: CodeEditor, CodeHighlight, AudioPlayer, VideoEmbed, VoiceInput, NodeCanvas, StreamingChat Use cases: Code editing, syntax highlighting, media playback, voice recognition, visual programming, chat interfaces

Charts & Data Visualization

Skill: composable-svelte-charts Package: @composable-svelte/​charts Components: Chart, ChartPrimitive, ChartTooltip Use cases: Data visualization, interactive charts, statistical plots

Maps & Geospatial

Skill: composable-svelte-maps Package: @composable-svelte/​maps Components: Map, MapPrimitive, GeoJSONLayer, HeatmapLayer, Popup, TileProviderControl Use cases: Interactive maps, geospatial data, location-based features


COMPONENT SELECTION DECISION TREE

Navigation Components

What kind of overlay?
│
├─ Full-screen important action → Modal
├─ Bottom panel (mobile-first) → Sheet
├─ Side panel (navigation/​settings) → Drawer
├─ Quick confirmation (yes/​no) → Alert
└─ Contextual menu (dropdown) → Popover

Form Components

What kind of input?
│
├─ Single line text → Input
├─ Multi-line text → Textarea
├─ Boolean toggle → Checkbox or Switch
├─ One from many options → RadioGroup or Select
├─ Autocomplete/​search → Combobox
└─ Date/​time → Input type="date" or Input type="time"

Data Display

What kind of data?
│
├─ Tabular data → Table
├─ List of items → Cards or List
├─ Status/​label → Badge
├─ User profile → Avatar
└─ Metrics/​stats → Card with metrics

Feedback

What kind of feedback?
│
├─ Loading state → Spinner or Skeleton
├─ Progress indicator → Progress
├─ Success/​error notification → Toast
└─ Confirmation needed → Alert

CUSTOM COMPONENT GUIDELINES

Principles for Building Custom Components:

  1. No $state for Application State: All state that affects behavior or can be tested must be in the store
  2. Dispatch Actions: User interactions dispatch actions to the store
  3. Read from Store: Render based on $store.state
  4. Use $derived: For computed values derived from store state
  5. Props for Configuration: Static configuration (labels, styles) can be props

Example Custom Component:

<script lang="ts">
  import type { Store } from '@composable-svelte/​core';

  export let store: Store<State, Action>;
  export let label: string; // Static config
  export let variant: 'primary' | 'secondary' = 'primary'; // Static config

  // Derived from store
  const isDisabled = $derived($store.isLoading || $store.hasErrors);
  const displayText = $derived($store.count > 0 ? `${label} (${$store.count})` : label);
</​script>

<button
  class={variant}
  disabled={isDisabled}
  onclick={() => store.dispatch({ type: 'buttonClicked' })}
>
  {displayText}
</​button>

ACCESSIBILITY PATTERNS

Keyboard Navigation

All interactive components support keyboard navigation:

  • Tab: Move focus between elements
  • Enter/​Space: Activate buttons, toggles
  • Escape: Close modals, popovers, dropdowns
  • Arrow keys: Navigate lists, select options

Screen Reader Support

Components include ARIA attributes:

  • aria-label: Descriptive labels
  • aria-expanded: Expanded/​collapsed state
  • aria-selected: Selected state
  • role: Semantic roles

Focus Management

Components manage focus:

  • Modal traps focus inside dialog
  • Popover returns focus to trigger on close
  • Forms focus first invalid field on submit

STYLING PATTERNS

Tailwind Integration

All components use Tailwind CSS classes:

<Button class="bg-primary text-primary-foreground hover:bg-primary/​90">
  Click me
</​Button>

Custom Styles

Override with custom CSS:

<Card class="custom-card">
  <CardContent>
    ...
  </​CardContent>
</​Card>

<style>
  .custom-card {
    background: linear-gradient(to right, #667eea 0%, #764ba2 100%);
  }
</​style>

SUMMARY

This skill covers the component library for Composable Svelte:

  1. Navigation Components: Modal, Sheet, Drawer, Alert, Popover
  2. Form Components: Input, Select, Checkbox, RadioGroup, Switch, Textarea, Combobox
  3. Data Display: Table, Card, Badge, Avatar
  4. Feedback: Toast, Progress, Skeleton, Spinner
  5. Layout: Accordion, Tabs, Collapsible
  6. 3D Graphics: Scene, Camera, Light, Mesh (box, sphere, cylinder, torus, plane)
  7. Component Selection: Decision trees for choosing components
  8. Custom Components: Guidelines for building custom components
  9. Accessibility: Keyboard, screen reader, focus management
  10. Styling: Tailwind integration, custom styles

Remember: Props for config, state in store, dispatch for interactions. Use the right component for each use case.

For navigation implementation, see composable-svelte-navigation skill. For form integration, see composable-svelte-forms skill. For core architecture, see composable-svelte-core skill. For testing components, see composable-svelte-testing skill.

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View