cmlabs-ui
v0.2.0
Published
The official cmlabs UI component library — install real, editable React + Tailwind v4 components and design tokens from cmlabs.co directly into your project via a shadcn-style CLI.
Maintainers
Readme
cmlabs-ui
The official UI component library for cmlabs.co — an Indonesia-based enterprise SEO & GEO (Generative Engine Optimization) agency and MarTech studio. Install real, editable React + Tailwind v4 components and design tokens directly into your project via a shadcn-style CLI. Nothing gets installed as a node_modules dependency; every add writes real, editable source files into your own repo.
Usage
npx cmlabs-ui list
npx cmlabs-ui add base-button
npx cmlabs-ui add base-button badge input textarea container
npx cmlabs-ui add basic-card dashboard-card
npx cmlabs-ui add theme fontsEvery component's own npm dependencies (Radix packages, framer-motion, cmdk, etc) are installed automatically — add detects your package manager from the lockfile in the target directory (pnpm-lock.yaml → pnpm, yarn.lock → yarn, bun.lockb → bun, package-lock.json or nothing found → npm) and runs its install command for you. Anything already declared in your package.json (dependencies, devDependencies, peerDependencies, or optionalDependencies) is detected and skipped, so add never reinstalls or bumps a version you already have pinned.
Flags:
--force— overwrite files that already exist (default: skip existing files)--cwd <path>— install into<path>instead of the current directory--skip-install— don't auto-install npm dependencies, just print the command to run yourself
Available items
| Name | Type | What it does |
| --------------------------- | --------------------- | ----------------------------------------------------------------------------------------------- |
| utils | lib | The cn() helper (clsx + tailwind-merge) — auto-installed as a dependency where needed |
| base-button | components:ui | Button / LinkButton — 13 variants × 6 sizes |
| badge | components:ui | Badge — 11 variants × 4 sizes, mirrors the real cmlabs.co Badge |
| skeleton | components:ui | Skeleton — pulsing loading placeholder, no built-in shape |
| avatar | components:ui | Avatar (Radix) — automatic image-load-failure fallback |
| separator | components:ui | Separator (Radix) — horizontal/vertical divider line |
| table | components:ui | Table and its 8 parts — native <table> styling wrapper, no Radix |
| callout | components:ui | Callout — icon + heading + description notice box |
| scroll-area | components:ui | ScrollArea / ScrollBar (Radix) — custom-styled scrollbar |
| input | components:ui | Input — icons, size variants |
| textarea | components:ui | Textarea |
| select | components:ui | Select and its 9 parts (Radix) |
| checkbox | components:ui | Checkbox (Radix) |
| radio-group | components:ui | RadioGroup / RadioGroupItem (Radix) |
| switch | components:ui | Switch (Radix) |
| label | components:ui | Label (Radix) |
| popover | components:ui | Popover (Radix) — anchored floating content, dropdown wrapper for the date pickers |
| dialog | components:ui | Dialog (Radix) — centered modal overlay, focus trap + scroll lock built in |
| sheet | components:ui | Sheet (Radix, same primitive as Dialog) — edge-anchored slide-in panel, 5 side variants |
| tooltip | components:ui | Tooltip (Radix) — hover/focus hint, requires TooltipProvider mounted once at the root |
| command | components:ui | Command / CommandDialog (cmdk) — searchable list with built-in fuzzy filtering |
| form | components:ui | react-hook-form wrapper — Form/FormField/FormItem/FormLabel/FormControl/FormMessage |
| field | components:ui | Generic field layout, not tied to react-hook-form |
| input-group | components:ui | Input + addon (icon/text/button) fused into one unit |
| month-picker | components:ui | Custom month/year grid picker (date-fns based, not a shadcn primitive) |
| calendar | components:ui | Day-level calendar wrapping react-day-picker |
| container | components:ui | Page-width wrapper (1336px, Tailwind v4) |
| basic-card | components:advanced | A plain, fully-editable card block — no CardHeader/CardContent sub-components |
| content-list-card | components:advanced | Card Pattern A — image on top, shadow-smooth |
| feed-article-card | components:advanced | Card Pattern B — large rounded corners, footer meta bar |
| dashboard-card | components:advanced | Card Pattern C — bordered panel, header/footer bands |
| pricing-featured-card | components:advanced | Card Pattern D — default vs. solid-brand-color featured variant |
| whatsapp-cta | components:advanced | Floating WhatsApp CTA button |
| pill-cta-hero | components:advanced | Hero/section pill CTA pair |
| outline-pill-button | components:advanced | Outline pill "Learn more" button |
| dropdown-pill-button | components:advanced | Purple pill dropdown trigger |
| carousel-arrow-nav-button | components:advanced | Round arrow carousel nav + dots |
| small-text-button | components:advanced | Small text link + card-style option button |
| disclosure-button | components:advanced | Text-only accordion/disclosure trigger |
| theme | theme | The full cmlabs.co color palette + radius as Tailwind v4 @theme tokens |
| fonts | assets | Satoshi font files (variable + static weights) |
Each card item is its own registry entry rather than one generic card —
install just the pattern you need. Run npx cmlabs-ui list for the
current, authoritative list.
Local development
This package's registry/*.json files are generated from the real source in this repo (app/components/ui/*.tsx, app/components/examples/*.tsx, lib/utils.ts, templates/theme.css, public/fonts/satoshi/*) — don't hand-edit them. After changing a component, regenerate:
node packages/cli/scripts/build-registry.mjsTesting without publishing
node packages/cli/bin/cli.mjs list
node packages/cli/bin/cli.mjs add base-button --cwd /path/to/some/test-projectOr npm link this package to get a real cmlabs-ui command on your PATH pointing at this local copy.
Publishing
Published at npmjs.com/package/cmlabs-ui. npm version numbers are immutable — bump version in packages/cli/package.json before every npm publish, or the registry rejects it with a 403 ("cannot publish over the previously published version").
