A simple, lightweight alternative to Storybook for showcasing Svelte component variations. Features a clean sidebar navigation layout inspired by Storybook, but without the complexity—just a straightforward way to display your UI components and their different states.
npm install svelte-catalog
<script>
import { Catalog, Section, Variant } from 'svelte-catalog';
import Button from './Button.svelte';
</script>
<Catalog title="My Component Library">
<Section title="Buttons" description="Various button styles">
<Variant title="Primary Button" description="Main call-to-action">
<Button variant="primary">Click me</Button>
</Variant>
<Variant title="Secondary Button">
<Button variant="secondary">Cancel</Button>
</Variant>
<Variant title="Disabled State">
<Button disabled>Disabled</Button>
</Variant>
</Section>
<Section title="More Components">
<Variant title="Another Variant">
<!-- Your component here -->
</Variant>
</Section>
</Catalog>
CatalogThe main container that provides the sidebar layout and navigation structure.
Props:
title (string, optional) - The catalog title shown in sidebar header (default: "Component Catalog")Example:
<Catalog title="Design System">
<!-- Sections go here -->
</Catalog>
Features:
SectionGroups related component variants together. Automatically creates a navigation link in the sidebar.
Props:
title (string, required) - Section heading (also used for nav link)description (string, optional) - Section descriptionExample:
<Section title="Form Elements" description="Input fields, checkboxes, and more">
<!-- Variants go here -->
</Section>
VariantDisplays a single component variation in a card with a title and preview area.
Props:
title (string, required) - Name of this variantdescription (string, optional) - Description of what this variant showsExample:
<Variant title="Loading State" description="Button with loading spinner">
<Button loading>Loading...</Button>
</Variant>
<script>
import { Catalog, Section, Variant } from 'svelte-catalog';
import Button from '$lib/Button.svelte';
import Card from '$lib/Card.svelte';
import Badge from '$lib/Badge.svelte';
</script>
<Catalog title="UI Component Library">
<Section title="Buttons" description="Interactive button components">
<Variant title="Button Variants" description="Different visual styles">
<div style="display: flex; gap: 1rem;">
<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="danger">Danger</Button>
</div>
</Variant>
<Variant title="Button Sizes" description="Small, medium, and large">
<div style="display: flex; gap: 1rem; align-items: center;">
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
</div>
</Variant>
<Variant title="Disabled State" description="Non-interactive button">
<Button disabled>Disabled</Button>
</Variant>
</Section>
<Section title="Cards" description="Content containers">
<Variant title="Basic Card">
<Card>
<h3>Title</h3>
<p>Card content goes here</p>
</Card>
</Variant>
<Variant title="Card with Shadow" description="Elevated appearance">
<Card shadow>
<h3>Elevated Card</h3>
<p>This card has a shadow effect</p>
</Card>
</Variant>
</Section>
<Section title="Badges" description="Status indicators and labels">
<Variant title="Status Badges">
<div style="display: flex; gap: 0.5rem;">
<Badge status="success">Active</Badge>
<Badge status="warning">Pending</Badge>
<Badge status="error">Failed</Badge>
</div>
</Variant>
</Section>
</Catalog>
The catalog comes with a clean, minimal design inspired by Storybook. The components use scoped styles that won't interfere with your component styles.
#f6f9fc)You can wrap the catalog in a container with custom CSS to adjust the appearance:
<div class="custom-catalog">
<Catalog title="My Library">
<!-- content -->
</Catalog>
</div>
<style>
.custom-catalog :global(.sidebar) {
background: #your-color;
}
</style>
Use flex layouts to show multiple states side-by-side:
<Variant title="All Button States">
<div style="display: flex; gap: 1rem; flex-wrap: wrap;">
<Button>Normal</Button>
<Button hover>Hover</Button>
<Button active>Active</Button>
<Button disabled>Disabled</Button>
</div>
</Variant>
Your components can have full interactivity:
<script>
let count = $state(0);
</script>
<Variant title="Counter Button">
<Button onclick={() => count++}>
Clicked {count} times
</Button>
</Variant>
Add inline styles to the variant content:
<Variant title="Light Button on Dark">
<div style="background: #1a1a1a; padding: 2rem; border-radius: 8px;">
<Button variant="light">Light Button</Button>
</div>
</Variant>
# Install dependencies
npm install
# Start dev server
npm run dev
# Build library
npm run build
Modern browsers with support for:
MIT