@classic-homes/theme-svelte

中文文档
1.44.0发布于 2026/11/06MITTypeScriptES Module近 30 天下载 5863

Svelte components for the Classic theme system

原始使用文档
文档目录24 节
  1. Installation
  2. Setup
  3. 1. Configure Tailwind CSS
  4. 2. Import Design Tokens
  5. Usage
  6. Components
  7. Core UI
  8. Layout
  9. Feedback
  10. Data Display
  11. Media
  12. Branding
  13. Notification Components (Optional)
  14. Error Handling
  15. Overview
  16. Recommended: Error Boundary Component
  17. Usage with AppShell
  18. Custom Fallback UI
  19. Toast Notifications
  20. Sidebar State
  21. TypeScript Support
  22. Svelte 5 Runes
  23. Accessibility
  24. License

@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-tokens

Setup

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 field
  • Textarea - Multi-line text input
  • Label - Form labels
  • Checkbox - Checkbox input
  • Switch - Toggle switch
  • Select - Dropdown select
  • FormField - Combined label + input + error handling

Layout

  • AppShell - Application wrapper with skip links and toast container
  • DashboardLayout - Sidebar + header layout for dashboards
  • PublicLayout - Header + footer layout for public pages
  • FormPageLayout - Centered form page layout
  • Sidebar - Navigation sidebar
  • Header - Page header
  • Footer - Page footer

Feedback

  • Alert - Alert messages (default, destructive, success, warning, info)
  • AlertDialog - Confirmation dialogs
  • Dialog - Modal dialogs
  • Toast - Toast notifications
  • ToastContainer - Toast notification container
  • Spinner - Loading spinner
  • Skeleton - Loading skeleton

Data Display

  • Card - Card container with header, content, footer
  • Badge - Status badges
  • DataTable - Sortable data table
  • Tabs - Tab navigation
  • Tooltip - Hover tooltips
  • DropdownMenu - Dropdown menus
  • Avatar - User avatars

Media

  • AspectRatio - Constrains content to a fixed width-to-height ratio
  • Image - Responsive image with lazy loading, placeholders, and error fallback
  • Video - Video player with themed controls, full keyboard support, and HLS/Cloudflare Stream playback
  • Audio - Compact audio player with themed controls
  • MediaEmbed - Lazy YouTube, Vimeo, Cloudflare Stream, and Matterport 3D tour embeds that load nothing until clicked
  • MediaGrid - Responsive gallery of media thumbnails
  • MediaCarousel - Swipeable media slides with dots, thumbnails, and optional autoplay
  • Lightbox - Full-screen media viewer with zoom, pan, and keyboard navigation

Adaptive streaming and Cloudflare Stream

Video plays HLS playlists, including Cloudflare Stream, with the same controls as a self-hosted file. Safari plays HLS natively; other browsers need hls.js, an optional peer dependency:

npm install hls.js
// once, at app startup
import { setHlsLoader } from '@classic-homes/theme-svelte';

setHlsLoader(() => import('hls.js').then((m) => m.default));

The import lives in your code rather than in this package, so consumers who never play a stream are not forced to install hls.js to build.

<script lang="ts">
  import { Video, cloudflareStream } from '@classic-homes/theme-svelte';

  const tour = cloudflareStream('a1b2c3d4e5f6', {
    customerCode: 'abc123',
    title: 'Product tour',
  });
</script>

<Video item={tour} />

cloudflareStream() derives the HLS playlist and poster from Stream's URL scheme with no API call. Pass a signed playback token in place of the video id for private videos. For Cloudflare's own player, use MediaEmbed with provider="cloudflare".

Branding

  • LogoMain - Main logo component
  • LoadingLogo - Animated loading logo

Notification Components (Optional)

Notification UI components are available via a separate entry point. This makes the @classic-homes/notifications dependency optional - you only need it if you use these components.

# Install the notifications package if using notification components
npm install @classic-homes/notifications
<script>
  // Import notification components from the /notifications subpath
  import {
    NotificationList,
    NotificationItem,
    NotificationBadge,
    NotificationDialog,
    NotificationFilters,
    NotificationBulkActions,
  } from '@classic-homes/theme-svelte/notifications';

  // Import types and utilities from the notifications package
  import type { Notification } from '@classic-homes/notifications/core';
</script>

Available notification components:

  • NotificationBadge - Unread count badge
  • NotificationItem - Single notification card
  • NotificationList - List of notifications with empty state
  • NotificationDialog - Detail dialog for a notification
  • NotificationFilters - Filter tabs (all/read/unread)
  • NotificationBulkActions - Bulk action toolbar

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.

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 toast
  • toastStore.error(message, options?) - Red error toast (persistent by default)
  • toastStore.warning(message, options?) - Yellow warning toast
  • toastStore.info(message, options?) - Blue info toast
  • toastStore.add(toast) - Add custom toast
  • toastStore.remove(id) - Remove toast by ID
  • toastStore.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

版本与发布记录

@classic-homes/theme-svelte 共发布 129 个版本,首次发布于 2026/01/09;过去 12 个月发布了 129 个版本。

版本发布日期距今
1.44.0latest2026/11/064 天前
1.43.02026/11/064 天前
1.42.32026/11/055 天前
1.42.22026/11/055 天前
1.42.12026/11/055 天前
1.41.02026/11/055 天前

关于 @classic-homes/theme-svelte 的常见问题

@classic-homes/theme-svelte 是什么?

Svelte components for the Classic theme system

如何安装 @classic-homes/theme-svelte?

在项目目录运行 npm install @classic-homes/theme-svelte,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:svelte(^5.31.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@classic-homes/theme-svelte 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@classic-homes/theme-svelte 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@classic-homes/theme-svelte 可以商用吗?

@classic-homes/theme-svelte 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@classic-homes/theme-svelte 的下载量有多少?

根据 npm 官方下载统计,@classic-homes/theme-svelte 在 2026/10/10 – 2026/11/08 这 30 天内被下载 5,863 次,日均约 195 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@classic-homes/theme-svelte 还在维护吗?

最新版本 1.44.0 发布于 2026/11/06(4 天前);至今共发布 129 个版本,其中过去 12 个月发布了 129 个;首次发布于 2026/01/09。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。