composable-svelte-components
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
$storefor 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 openonOpenChange: (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: booleanonOpenChange: (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 fromopen: booleanonOpenChange: (open: boolean) => void
Alert
Confirmation dialog, centered, smaller than Modal.
When to use: Destructive actions, confirmations, yes/no decisions.
Props:
open: booleanonOpenChange: (open: boolean) => void
Popover
Contextual menu positioned near trigger element.
When to use: Dropdown menus, tooltips, context menus.
Props:
open: booleanonOpenChange: (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 typevalue: string- Current valueoninput: (e: Event) => void- Change handlerplaceholder: string- Placeholder textdisabled: 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 valueonValueChange: (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 stateonCheckedChange: (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 valueonValueChange: (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: booleanonCheckedChange: (checked: boolean) => void
Textarea
Multi-line text input.
Props:
value: stringoninput: (e: Event) => voidrows: number- Number of visible rowsplaceholder: string
Combobox
Autocomplete dropdown.
Props:
value: string- Selected valueoptions: Array<{ label: string; value: string }>- Available optionsonValueChange: (value: string) => void- Selection handleronSearchChange: (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:
- No
$statefor Application State: All state that affects behavior or can be tested must be in the store - Dispatch Actions: User interactions dispatch actions to the store
- Read from Store: Render based on
$store.state - Use
$derived: For computed values derived from store state - 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 labelsaria-expanded: Expanded/collapsed statearia-selected: Selected staterole: 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:
- Navigation Components: Modal, Sheet, Drawer, Alert, Popover
- Form Components: Input, Select, Checkbox, RadioGroup, Switch, Textarea, Combobox
- Data Display: Table, Card, Badge, Avatar
- Feedback: Toast, Progress, Skeleton, Spinner
- Layout: Accordion, Tabs, Collapsible
- 3D Graphics: Scene, Camera, Light, Mesh (box, sphere, cylinder, torus, plane)
- Component Selection: Decision trees for choosing components
- Custom Components: Guidelines for building custom components
- Accessibility: Keyboard, screen reader, focus management
- 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 from linehaul-ai/linehaulai-claude-marketplace
geospatial-postgis-patterns
Implement geofences, spatial queries, real-time tracking, and mapping features in laneweaverTMS using PostGIS and PGRouting. Use when building location-based features, distance calculations, ETA predictions, or fleet visualization.
83quickbooks-online-api
Expert guide for QuickBooks Online API integration covering authentication, CRUD operations, batch processing, and best practices for invoicing, payments, and customer management.
61rbac-authorization-patterns
Provide patterns for implementing Role-Based Access Control and multi-tenant authorization in laneweaverTMS. Use when implementing user roles, permissions, tenant isolation, Echo authorization middleware, RLS policies for multi-tenant access, or JWT claims structure for freight brokerage applications.
61slack-block-kit
Build Slack Block Kit UIs for messages, modals, and Home tabs. Use when creating Slack notifications, interactive forms, bot responses, app dashboards, or any Slack UI. Covers blocks (Section, Actions, Input, Header), elements (Buttons, Selects, Date pickers), composition objects, and the slack-block-builder library.
44svelte-flow
Build node-based editors, interactive diagrams, and flow visualizations using Svelte Flow. Use when creating workflow editors, data flow diagrams, organizational charts, mindmaps, process visualizations, DAG editors, or any interactive node-graph UI. Supports custom nodes/edges, layouts (dagre, hierarchical), animations, and advanced features like proximity connect, floating edges, and contextual zoom.
35testcontainers-go
Use this skill when writing Go integration tests with Docker containers, using testcontainers-go modules (postgres, redis, kafka, etc.), setting up container-based test infrastructure, or configuring container networking and wait strategies. Covers 62+ pre-configured modules, cleanup patterns, and multi-container setups.
34