@classic-homes/theme-svelte
v0.1.26
Published
Svelte components for the Classic theme system
Downloads
2,609
Readme
@classic-homes/theme-svelte
Svelte 5 components for the Classic Theme design system. Built on Bits UI primitives and styled with Tailwind CSS.
Installation
npm install @classic-homes/theme-svelte @classic-homes/theme-tokensSetup
1. Configure Tailwind CSS
Add the Classic Theme preset to your tailwind.config.js:
import preset from '@classic-homes/theme-tailwind-preset';
export default {
presets: [preset],
content: [
'./src/**/*.{html,js,svelte,ts}',
'./node_modules/@classic-homes/theme-svelte/**/*.{html,js,svelte,ts}',
],
};2. Import Design Tokens
Import the CSS tokens in your app's root CSS file:
@import '@classic-homes/theme-tokens/css';Or in your root layout:
<script>
import '@classic-homes/theme-tokens/css';
</script>Usage
<script>
import { Button, Card, CardHeader, CardTitle, CardContent } from '@classic-homes/theme-svelte';
</script>
<Card>
<CardHeader>
<CardTitle>Welcome</CardTitle>
</CardHeader>
<CardContent>
<Button variant="default">Click me</Button>
</CardContent>
</Card>Components
Core UI
Button- Buttons with variants (default, secondary, destructive, outline, ghost, link)Input- Text input fieldTextarea- Multi-line text inputLabel- Form labelsCheckbox- Checkbox inputSwitch- Toggle switchSelect- Dropdown selectFormField- Combined label + input + error handling
Layout
AppShell- Application wrapper with skip links and toast containerDashboardLayout- Sidebar + header layout for dashboardsPublicLayout- Header + footer layout for public pagesFormPageLayout- Centered form page layoutSidebar- Navigation sidebarHeader- Page headerFooter- Page footer
Feedback
Alert- Alert messages (default, destructive, success, warning, info)AlertDialog- Confirmation dialogsDialog- Modal dialogsToast- Toast notificationsToastContainer- Toast notification containerSpinner- Loading spinnerSkeleton- Loading skeleton
Data Display
Card- Card container with header, content, footerBadge- Status badgesDataTable- Sortable data tableTabs- Tab navigationTooltip- Hover tooltipsDropdownMenu- Dropdown menusAvatar- User avatars
Branding
LogoMain- Main logo componentLoadingLogo- Animated loading logo
Error Handling
Overview
Components in this library do not include built-in error boundaries to give you full control over error handling. We recommend implementing error handling at your application's root level.
Recommended: Error Boundary Component
Create an ErrorBoundary component to catch and handle errors gracefully:
<!-- src/lib/ErrorBoundary.svelte -->
<script lang="ts">
import type { Snippet } from 'svelte';
import { Button, Alert, AlertDescription } from '@classic-homes/theme-svelte';
interface Props {
children: Snippet;
fallback?: Snippet<[Error, () => void]>;
}
let { children, fallback }: Props = $props();
let error = $state<Error | null>(null);
function reset() {
error = null;
}
$effect(() => {
const handleError = (e: ErrorEvent) => {
e.preventDefault();
error = e.error || new Error(e.message);
};
const handleUnhandledRejection = (e: PromiseRejectionEvent) => {
e.preventDefault();
error = e.reason instanceof Error ? e.reason : new Error(String(e.reason));
};
window.addEventListener('error', handleError);
window.addEventListener('unhandledrejection', handleUnhandledRejection);
return () => {
window.removeEventListener('error', handleError);
window.removeEventListener('unhandledrejection', handleUnhandledRejection);
};
});
</script>
{#if error}
{#if fallback}
{@render fallback(error, reset)}
{:else}
<div class="flex min-h-screen items-center justify-center p-4">
<div class="w-full max-w-md space-y-4">
<Alert variant="destructive">
<AlertDescription>
<strong>Something went wrong</strong>
<p class="mt-2 text-sm">{error.message}</p>
</AlertDescription>
</Alert>
<Button onclick={reset} variant="outline" class="w-full">Try again</Button>
</div>
</div>
{/if}
{:else}
{@render children()}
{/if}Usage with AppShell
Wrap your AppShell with the ErrorBoundary:
<!-- src/routes/+layout.svelte -->
<script>
import { AppShell } from '@classic-homes/theme-svelte';
import ErrorBoundary from '$lib/ErrorBoundary.svelte';
</script>
<ErrorBoundary>
<AppShell>
<slot />
</AppShell>
</ErrorBoundary>Custom Fallback UI
You can provide a custom fallback UI:
<ErrorBoundary>
{#snippet fallback(error, reset)}
<div class="error-page">
<h1>Oops!</h1>
<p>{error.message}</p>
<button onclick={reset}>Reload</button>
</div>
{/snippet}
<AppShell>
<slot />
</AppShell>
</ErrorBoundary>Toast Notifications
The library includes a toast store for managing notifications:
<script>
import { toastStore, Button } from '@classic-homes/theme-svelte';
function showSuccess() {
toastStore.success('Operation completed successfully!');
}
function showError() {
toastStore.error('Something went wrong', { title: 'Error' });
}
</script>
<Button onclick={showSuccess}>Show Success</Button>
<Button onclick={showError} variant="destructive">Show Error</Button>Toast methods:
toastStore.success(message, options?)- Green success toasttoastStore.error(message, options?)- Red error toast (persistent by default)toastStore.warning(message, options?)- Yellow warning toasttoastStore.info(message, options?)- Blue info toasttoastStore.add(toast)- Add custom toasttoastStore.remove(id)- Remove toast by IDtoastStore.clear()- Remove all toasts
Sidebar State
For layouts with collapsible sidebars, use the sidebar store:
<script>
import { sidebarStore } from '@classic-homes/theme-svelte';
function toggleSidebar() {
sidebarStore.toggle();
}
</script>
<button onclick={toggleSidebar}>
{sidebarStore.isOpen ? 'Close' : 'Open'} Sidebar
</button>TypeScript Support
All components are fully typed. Import types as needed:
import type {
NavItem,
NavSection,
User,
Tab,
FileMetadata,
DataTableColumn,
SelectOption,
} from '@classic-homes/theme-svelte';Svelte 5 Runes
All components use Svelte 5 runes syntax:
$props()for component props$state()for reactive state$derived()for computed values$effect()for side effects$bindable()for two-way binding
Accessibility
Components are built with accessibility in mind:
- Proper ARIA attributes
- Keyboard navigation support
- Focus management
- Screen reader friendly
- Skip links in AppShell
License
MIT
