@juspay/svelte-ui-components
v2.14.1
Published
A themeable Svelte 5 UI component library with CSS custom property driven styling
Readme
@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-componentsRequires 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 |
Navigation & Structure
| 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)Snippetfor 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-mcpIt 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 filesProject 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:
- Lints the codebase
- Determines semver bump from conventional commit message (
feat:= minor,fix:= patch,!= major) - Bumps
package.jsonversion and generates a changelog - Builds the package
- Creates a GitHub release with a git tag
- Publishes to npm (
--access public)
License
MIT
