Shared UI components for CSET club web apps - Svelte 5 + Tailwind CSS v4 + bits-ui, styled in the club's Blueprint/Schematic design system (self-hosted Geist fonts, navy/PCB-blue palette, dot-grid background, corner-tick and circuit-trace accents, accessible light/dark theme switch).
Not published to npm; install directly from GitHub.
pnpm add github:cset-cbt/cset-ui#v0.3.1Pin to a tag (shown above) or a commit SHA for reproducible installs. Requires svelte@^5 and @sveltejs/kit@^2 in the consuming app (peer dependencies) and Tailwind CSS v4 with @tailwindcss/vite.
In your app's src/app.css:
@import 'tailwindcss';
@import 'cset-ui/styles.css';That's it — no extra Tailwind @source config needed in your app. cset-ui/styles.css declares its own @source pointing at this package's component files, and Tailwind v4 follows @source/@theme through @import chains, so your build automatically picks up every utility class used inside cset-ui's components. Fonts are plain relative url()s in the same file, so Vite's asset pipeline bundles them into your build automatically too — no manual font-copying step.
Then set data-theme="light" or "dark" on <html> (see applyTheme/readTheme below) and add an anti-flash inline script in app.html that sets it before first paint, same pattern as any of the CSET apps' src/app.html.
<script lang="ts">
import { Card, Button, InputField, PageHeader, ThemeToggle, Select, type SelectOption } from 'cset-ui';
let role = 'user';
const roles: SelectOption[] = [
{ value: 'admin', label: 'Quản trị viên' },
{ value: 'user', label: 'Thành viên' }
];
</script>
<Card>
<PageHeader eyebrow="CSET" title="Xin chào">Mô tả giao diện.</PageHeader>
<InputField label="Email" name="email" type="email" required />
<Select items={roles} bind:value={role} size="md" />
<Button type="submit">Xác nhận</Button>
</Card>Exports: Logo, Button, Card, PageHeader, InputField, FormMessage, ThemeToggle, VersionBadge, CircuitDivider, KeyboardIllustration, Select, Toast, Toaster, toast, Dialog, Popover, Tooltip, Badge, Avatar, AvatarGroup, Tabs, Accordion, Breadcrumb, Switch, Checkbox, RadioGroup, Slider, Skeleton, DropdownMenu, CommandPalette, plus readTheme/applyTheme/toggleThemeWithTransition/Theme from the theme utility.
VersionBadge reads $app/environment's version, which reflects whichever consuming app renders it. Set kit.version.name in that app's own svelte.config.js from its own package.json version.
All components read CSS custom properties (--ui-*, --brand-*) defined in styles.css's light/dark [data-theme] blocks. To reskin an app slightly without forking a component, override the relevant --ui-* variable in that app's own CSS after the cset-ui/styles.css import. Do not edit files inside node_modules.
This repo ships its built output in git (dist/, styles.css at the repo root) rather than relying on a build-on-install step, since pnpm ignores lifecycle scripts (prepare/postinstall) from git dependencies by default unless explicitly allowlisted. So after editing src/lib/:
pnpm run package # rebuilds dist/ and styles.css
git add -A
git commit -m "..."
git tag vX.Y.Z
git push && git push --tagsConsuming apps pin an exact tag/SHA (see Install above) and bump it deliberately. There is no auto-update. A component change here can affect every app using it; review before bumping a consumer's pinned ref.
pnpm install
pnpm run check # svelte-check
pnpm run package # build dist/ + copy styles.cssDocumentation & live component showcase website: cset-ui-docs (SvelteKit + Cloudflare Workers). Preview components, interactive props, and copy code snippets directly.