npm.io
0.28.0 • Published 21h ago

@skdx/svelte

Licence
MIT
Version
0.28.0
Deps
1
Size
3.5 MB
Vulns
0
Weekly
0

@skdx/svelte

Headless, accessible, unstyled Svelte 5 components for the SkandaDX design system.

Every component ships behavior, accessibility, and state — no styles. Components render plain semantic HTML decorated with data-* attributes; you (or a SkandaDX brand package) style them with CSS against those attributes, typically using the --skdx-* tokens from @skdx/tokens. One component tree, any brand.

@skdx/svelte (behavior) + --skdx-* variables (theme) + your CSS (skin) = branded UI

Installation

pnpm add @skdx/svelte
# or: npm install @skdx/svelte

Svelte 5.46 or newer is required (svelte is a peer dependency — components are authored with runes and snippets). The only runtime dependency is @floating-ui/dom, used for positioning overlays. Components ship as .svelte source with TypeScript declarations, so your app's Svelte compiler compiles them.

Quick start

Components are exported unprefixed from the package root; every component also has a subpath export (@skdx/svelte/dialog/Dialog.svelte) if you prefer to import the file directly.

<script lang="ts">
  import {
    Dialog,
    DialogClose,
    DialogContent,
    DialogDescription,
    DialogTitle,
    DialogTrigger,
  } from '@skdx/svelte';
</script>

<Dialog>
  <DialogTrigger>Edit profile</DialogTrigger>
  <DialogContent class="panel">
    <DialogTitle>Edit profile</DialogTitle>
    <DialogDescription>Make changes to your profile here.</DialogDescription>
    <DialogClose>Close</DialogClose>
  </DialogContent>
</Dialog>

Nothing is styled until you say so:

.panel {
  background: var(--skdx-color-semantic-surface);
  color: var(--skdx-color-semantic-text);
  border-radius: var(--skdx-radius-lg);
  padding: var(--skdx-space-6);
}
.panel[data-state='open'] {
  animation: fade-in var(--skdx-motion-duration-normal) var(--skdx-motion-easing);
}

Conventions

  • Compound components. Complex widgets are split into parts (Tabs + TabsList + TabsTrigger + TabsContent) that share state through context. You compose exactly the DOM you want.
  • Data attributes are the styling API. State is exposed as data-state="open", data-disabled, data-orientation="horizontal", … — never as class names. The same hooks, with the same values, exist in all five framework packages.
  • Controlled or uncontrolled. Stateful components take value / defaultValue / onValueChange (open / defaultOpen / onOpenChange for overlays). Pass the controlled prop to own the state, or the default* prop to let the component manage it.
  • Accessible by default. Roles, ARIA wiring, focus trapping, roving tabindex, typeahead and Esc/outside-click dismissal are built in — see each component's Keyboard table in the docs.

Documentation

Live demos, props tables, keyboard maps and styling hooks for every component (with a Svelte tab on every example): https://skdx.skandadx.dev/components/.

Development

pnpm --filter @skdx/svelte build       # svelte-package → dist/
pnpm --filter @skdx/svelte test        # vitest + @testing-library/svelte
pnpm --filter @skdx/svelte typecheck   # svelte-check

Component demos live in the docs portal (apps/docs): pnpm --filter @skdx/docs dev.