Skip to content

codelitdev/design-system

Repository files navigation

@codelitdev/design-system

Shared tokens, Tailwind preset, and React primitives for CourseLit, MediaLit, SendLit, and FrontLit.

The tokens + Tailwind preset are the product; the React components are reference/fallback (see step 5). Consuming apps typically use only the CSS and the preset and keep their own shadcn components.

Install

Published to npm as a public package. The current release line is a prerelease under the alpha dist-tag.

Warning

latest currently also points at 0.1.0-alpha.0. npm always sets latest on a package's first-ever publish, regardless of --tag — this is unavoidable until a real stable version is cut, at which point publishing it moves latest forward automatically. Until then, always pin the exact version — do not npm install @codelitdev/design-system bare, and do not use a caret/tilde range (^0.1.0-alpha.0 would still resolve to a prerelease, which is at least explicit — but a bare install with no version silently means "whatever latest is," which right now is this alpha).

npm install @codelitdev/design-system@0.1.0-alpha.0

Inside a workspace/monorepo you can still consume it as workspace:* when the package is vendored locally.

Use in a shadcn app

  1. Import the token layer once, e.g. in app/globals.css:
@import "@codelitdev/design-system/styles.css";

This replaces the default shadcn :root/.dark block — variable names match, so existing shadcn components need no code changes.

  1. Extend your Tailwind config:
// tailwind.config.js
const codelitPreset = require("@codelitdev/design-system/tailwind-preset");
module.exports = {
  presets: [codelitPreset],
  content: [...],
};
  1. Scope the product on the <html> element (not <body>):
<html data-product="sendlit">  {/* courselit | medialit | sendlit | frontlit, omit for CodeLit amber */}

Important

Put data-product on <html>, not <body>. The product scope only overrides --primary/--ring; any token you alias at :root that references --primary (e.g. shadcn's --sidebar-primary: var(--primary)) resolves that var() at the declaring element. If the override sits on <body> (a child of :root), those :root aliases freeze to the base amber and never pick up the product accent — while direct bg-primary utilities still turn green, producing a confusing split.

  1. Fonts: load Hanken Grotesk + Spline Sans Mono via next/font/google (or your framework's font loader), mapped to --font-sans / --font-mono.

  2. Components — install from the shadcn registry (see Components below). These are real shadcn/Radix components styled to the design system, so your app's buttons/badges/cards are the DS's — no hand-porting. The plain-React src/components/ classes (components.css) remain as visual reference only.

  3. Logos: @codelitdev/design-system/assets/logo-<product>.svg.

Components (shadcn registry)

The design system ships its components as a shadcn registry so every product installs the same styled components (buttons, badges, cards, …) via the shadcn CLI — keeping all four apps on one component layer instead of each re-styling its own. They're standard shadcn/Radix components; they pull their look from the DS tokens, so make sure @codelitdev/design-system/styles.css is imported (above).

Add the registry namespace to your app's components.json:

{
  "registries": {
    "@codelit": "https://raw.githubusercontent.com/codelitdev/design-system/main/public/r/{name}.json"
  }
}

Then install components like any other shadcn component:

npx shadcn@latest add @codelit/button @codelit/badge @codelit/card

Or install a single component directly by URL, no config:

npx shadcn@latest add https://raw.githubusercontent.com/codelitdev/design-system/main/public/r/button.json

Available components

Component Notes
button primary / secondary / outline / ghost / soft / destructive; sm md lg (30/36/42px)
icon-button Square icon-only; ghost / outline; sm md
badge default / neutral / success / warning / destructive / outline; dot prop
card + CardHeader CardTitle CardDescription CardContent CardFooter
input Accent-wash focus ring; aria-invalid → destructive
textarea Multiline form of input
label 13px semibold field label
checkbox 18px, 5px radius, accent fill when checked
radio-group + RadioGroupItem
switch 36×21 track, accent when on
select Trigger matches input; token-styled popover
tabs Segmented; active trigger lifts onto a card surface
dialog Warm scrim, 16px radius; full Radix parts
tooltip Dark chip; TooltipProvider included
toast Presentational card (default/success/destructive) — drive with your own queue

Install everything at once:

npx shadcn@latest add @codelit/button @codelit/icon-button @codelit/badge @codelit/card \
  @codelit/input @codelit/textarea @codelit/label @codelit/checkbox @codelit/radio-group \
  @codelit/switch @codelit/select @codelit/tabs @codelit/dialog @codelit/tooltip @codelit/toast

Maintainers: component sources live in registry/codelit/ui/. After changing one, rebuild the served JSON with pnpm registry:build (→ public/r/*.json) and commit it — the raw-URL install serves those committed files.

Publishing

Prereleases go under the alpha dist-tag so a plain npm install never grabs one. Always publish with an explicit tagpublishConfig.tag is not honored by npm 11.x, so a bare npm publish would land on latest:

npm run release:alpha            # → npm publish --tag alpha
# add --otp=<code> if 2FA is enabled

Verify: npm view @codelitdev/design-system dist-tags should show the prerelease under alpha and leave latest untouched.

License

Apache-2.0 — see LICENSE.

Releases

Packages

Used by

Contributors

Languages