svelte-ui-components Svelte Themes

Svelte Ui Components

@juspay/svelte-ui-components

A themeable Svelte 5 component library where every visual property is a CSS custom property. Build any design system on top — no source changes needed.

npm install @juspay/svelte-ui-components

Requires svelte ^5.41.2 and type-decoder ^2.1.0 as peer dependencies.


Why This Library?

Most component libraries ship with a fixed look. Changing it means fighting overrides, patching internals, or forking.

This library takes a different approach: components are unstyled by default and expose every visual decision — colors, spacing, typography, borders, shadows, radii — as CSS custom properties. You define the design system. The components render it.

<!-- A button that looks however you want -->
<div class="my-theme">
  <Button text="Continue" onclick={handleClick} />
</div>

<style>
  .my-theme {
    --button-color: #000;
    --button-text-color: #fff;
    --button-border-radius: 8px;
    --button-padding: 12px 24px;
    --button-font-size: 14px;
    --button-font-weight: 600;
    --button-hover-color: #222;
    --button-border: 1px solid #333;
  }
</style>

Quick Start

<script lang="ts">
  import { Button, Input, Toggle, Toast } from '@juspay/svelte-ui-components';
</script>

<!-- Basic button -->
<Button text="Submit" onclick={() => console.log('clicked')} />

<!-- Input with validation -->
<Input
  value=""
  placeholder="Enter email"
  dataType="email"
  onStateChange={(state) => console.log(state)}
/>

<!-- Toggle switch -->
<Toggle checked={false} text="Dark mode" onclick={(val) => console.log(val)} />

Components

Inputs & Form Controls

Component Description Docs
Button Action trigger with circular loader, progress bar, icon/children snippets, and aria-expanded support. docs
Input Text field with built-in validation for email, phone, password, and custom patterns. Supports text transformers and textarea mode. docs
InputButton Input field fused with action buttons — for search bars, OTP entry, coupon codes. docs
Select Dropdown picker with single-select (with search), multi-select (checkboxes + Select All + Apply), and custom content slots. docs
Toggle Labeled on/off switch with sliding ball animation. docs
Checkbox Styled checkbox input with custom SVG checkmark. docs
Radio Styled radio button with custom circular indicator. docs
Slider Range slider with configurable min, max, step, and optional value display. docs
Choicebox Selectable option group with single-select (radio) or multi-select (checkbox) behavior and custom content. docs

Display & Data

Component Description Docs
Avatar Circular avatar with image (Img with fallback) or text initial. docs
Badge Icon with a numeric/text badge overlay in the corner. docs
GridItem Grid cell with icon, label, and loading overlay animation. docs
Icon Clickable icon with optional text label. docs
IconStack Layered horizontal stack of overlapping circular icons/avatars. docs
Img Image with automatic fallback on load error. docs
ListItem Multi-section list row with images, labels, and accordion expansion. docs
Pill Compact label/tag for status or categories, optionally clickable with a11y. docs
Status Full-screen status display for success/failure screens. docs
Table Sortable data table with sticky headers and per-cell scrolling. docs
RelativeTime Auto-updating relative time display ("5 minutes ago") with locale support and optional tooltip. docs

Feedback & Loading

Component Description Docs
Banner Sticky notification banner with icon snippet, dismiss button, link text, and click interaction. docs
BrandLoader Full-screen branded splash/loading animation. docs
Loader Circular spinner with gradient foreground. docs
LoadingDots Animated inline dot sequence with bounce/pulse animations. docs
Shimmer Loading placeholder with animated shimmer effect. All visuals via CSS variables. docs
Toast Animated slide-in notification with type variants and auto-dismiss. docs
Progress Horizontal progress bar with animated fill. docs
Gauge Semicircular gauge/meter with configurable segments and animated value. docs

Overlays & Panels

Component Description Docs
Modal Dialog overlay with configurable size, alignment, header, footer, transitions, and back-press support. docs
ModalAnimation Fly/fade transition wrapper for modal content. docs
OverlayAnimation Fade transition wrapper for overlay backgrounds. docs
Sheet Slide-in panel from any edge (left/right/top/bottom) with header, scrollable content, footer, and focus trap. docs
CommandMenu Command palette (Ctrl+K) with fuzzy search, grouped commands, and keyboard navigation. docs
ContextMenu Right-click context menu with nested submenus, separators, and keyboard navigation. docs
Menu Dropdown action menu with keyboard navigation, typeahead, disabled/danger items, and separators. docs
Tooltip Hover-triggered tooltip with configurable position and delay. docs
Component Description Docs
Accordion Expandable/collapsible container with CSS grid animation. docs
Carousel Horizontal content slider with swipe and pagination dots. docs
CheckListItem Checklist row with checkbox, label, and toggleable checked state. docs
Pagination Page navigation with previous/next buttons and numbered page links. docs
Scroller Overflowing item list with arrow navigation, gradient edges, drag-to-scroll, and snap support. docs
Stepper Multi-step progress indicator with completed, active, and pending states. docs
Step Individual step within a Stepper — renders number, label, and connector. docs
Tabs Tabbed interface with animated active indicator. docs
Toolbar Fixed header bar with back button, title, and customizable content areas. docs

Actions

Component Description Docs
Snippet Copyable command-line snippet with prompt prefix and copy button. docs
SplitButton Primary action button with dropdown secondary actions via Menu component. docs
KeyboardInput Keyboard shortcut display with styled key caps. docs
ThemeSwitcher Segmented control for light/dark/system theme switching. docs

Decorative

Component Description Docs
Book 3D book display with animated page turning. docs
Browser Browser window chrome frame for content display. docs
Phone Smartphone device frame for app previews. docs

Theming

How It Works

Every component reads its visual properties from CSS custom properties with sensible defaults. To create a theme, define the variables on any ancestor element:

/* theme.css */
.my-design-system {
  /* Button */
  --button-color: #0070f3;
  --button-text-color: #fff;
  --button-border-radius: 6px;
  --button-padding: 10px 20px;
  --button-font-family: 'Inter', sans-serif;
  --button-font-size: 14px;
  --button-hover-color: #0060df;

  /* Input */
  --input-background: #fafafa;
  --input-border: 1px solid #eaeaea;
  --input-radius: 6px;
  --input-font-family: 'Inter', sans-serif;
  --input-focus-border: 1px solid #0070f3;

  /* Toast */
  --toast-border-radius: 8px;
  --toast-font-family: 'Inter', sans-serif;
  --toast-success-background-color: #0070f3;

  /* Modal */
  --modal-border-radius: 12px;
  --modal-content-background-color: #fff;
  --background-color: #00000066;
}
<div class="my-design-system">
  <Button text="Save" onclick={save} />
  <Input value="" placeholder="Search..." />
</div>

Scoped Theming

Because CSS variables cascade, you can scope different themes to different parts of your app:

<div class="light-theme">
  <Button text="Light" onclick={handleClick} />
</div>

<div class="dark-theme">
  <Button text="Dark" onclick={handleClick} />
</div>

<style>
  .light-theme {
    --button-color: #fff;
    --button-text-color: #000;
    --button-border: 1px solid #eaeaea;
  }
  .dark-theme {
    --button-color: #111;
    --button-text-color: #fff;
    --button-border: 1px solid #333;
  }
</style>

CSS Variable Reference

Each component documents its full set of CSS variables in the docs/ directory. The variable naming convention follows the pattern:

--{component}-{element}-{property}

For example:

  • --button-color — button background color
  • --input-error-msg-text-color — input error message text color
  • --modal-footer-primary-button-border-radius — border radius of the primary button inside a modal footer
  • --toast-success-background-color — background color for success variant toasts

Props & Types

Components use a typed props pattern split into mandatory, optional, and event properties:

// Every component follows this pattern
type ButtonProperties = OptionalButtonProperties & ButtonEventProperties;

type OptionalButtonProperties = {
  text?: string;
  enable?: boolean;
  disabled?: boolean;
  showLoader?: boolean;
  loaderType?: 'Circular' | 'ProgressBar';
  type?: 'submit' | 'reset' | 'button';
  icon?: Snippet;
  children?: Snippet;
  ariaLabel?: string;
  ariaExpanded?: boolean;
  // ...
};

type ButtonEventProperties = {
  onclick?: (event: MouseEvent) => void;
  onkeyup?: (event: KeyboardEvent) => void;
};

All types are exported from the package:

import type {
  ButtonProperties,
  InputProperties,
  ModalProperties,
  SelectProperties,
  ToastProperties,
  MenuItem,
  SheetSide
  // ...
} from '@juspay/svelte-ui-components';

Svelte 5 Patterns

This library is built on Svelte 5 and uses its modern APIs:

  • $props() for declaring component properties
  • $state() and $derived() for reactive state
  • $bindable() for two-way bound props (e.g., Sheet.open, Banner.visible, Button.showProgressBar)
  • Snippet for composable content slots (e.g., Button.icon, Sheet.content, Banner.rightContent)
<script lang="ts">
  import { Sheet } from '@juspay/svelte-ui-components';

  let open = $state(false);
</script>

<button onclick={() => (open = true)}>Open</button>

<Sheet bind:open title="Settings" side="right">
  {#snippet content()}
    <p>Sheet body goes here.</p>
  {/snippet}
  {#snippet footer()}
    <button onclick={() => (open = false)}>Done</button>
  {/snippet}
</Sheet>

MCP Server

An MCP (Model Context Protocol) server ships as a separate package for AI-assisted development:

npm install @juspay/svelte-ui-components-mcp

It provides full component documentation — props, events, CSS variables, type references — through a standard MCP tool interface. Useful for integrating component knowledge into AI coding assistants.


Development

pnpm install       # install dependencies
pnpm dev           # start dev server with hot reload
pnpm build         # build the library (vite + svelte-package + publint)
pnpm test          # run integration + unit tests
pnpm lint          # check formatting and lint rules
pnpm format        # auto-format source files

Project Structure

src/lib/
  {Component}/
    {Component}.svelte     # component implementation
    properties.ts          # prop type definitions
  types.ts                 # shared types (ValidationState, InputDataType, etc.)
  utils.ts                 # shared utilities (validateInput, createDebouncer)
  index.ts                 # public exports

docs/                      # component documentation (one markdown file per component)
mcp/                       # MCP server package (separate npm package)

Release

Pushing to the release branch triggers an automated CI pipeline:

  1. Lints the codebase
  2. Determines semver bump from conventional commit message (feat: = minor, fix: = patch, ! = major)
  3. Bumps package.json version and generates a changelog
  4. Builds the package
  5. Creates a GitHub release with a git tag
  6. Publishes to npm (--access public)

License

MIT

Top categories

Loading Svelte Themes