@viibestack/ui
@viibestack/ui
Dependency-free React UI kit -- a Feather/Lucide-style outline icon set (~28 icons, ported from services/portal/frontend/src/Icons.tsx) plus core components (Button, Card, Input, Textarea, Select, Badge, Modal, EmptyState, Spinner, Alert, Checkbox, Switch, Avatar, Tabs, and Table primitives). No runtime dependencies beyond react/react-dom, so it's safe to use anywhere React runs, including apps deployed on the OpenNext Cloudflare Workers adapter (no Node-native code, nothing that needs fs/stream/native bindings). Styled with plain Tailwind utility classes -- the consuming app needs Tailwind already set up (every app this is meant for already has it, see scratch-scaffold.ts).
Usage
import { CheckIcon, TrashIcon, Button, Card, Input, Modal } from "@viibestack/ui";
<CheckIcon size={16} color="green" />
<TrashIcon className="text-red-500" />
<Button variant="primary" size="md" onClick={...}>Save</Button>
<Card title="Recent activity">...</Card>
<Input label="Email" type="email" error={errors.email} />
Every icon takes the same optional props: size (number, default 20), color (default "currentColor", so it follows the surrounding text color / a Tailwind text-* class unless overridden), and className.
Components
- Button --
variant:primary | secondary | outline | ghost | danger,size:sm | md | lg, plus every native<button>prop. - Card -- optional
title, wraps children in a bordered/padded container. - Input / Textarea / Select -- optional
labelanderror, plus every native form prop.Selecttakesoptions: {value, label}[]and an optionalplaceholder. - Badge --
variant:neutral | success | warning | danger | info. - Modal --
open,onClose, optionaltitle; portals todocument.body, closes on Escape or backdrop click. - EmptyState --
title, optionalicon/description/action-- the "nothing here yet" placeholder. - Spinner --
size(number, default 20). - Alert --
variant:info | success | warning | danger, optionaltitleandonDismiss. - Checkbox -- optional
label, plus every native checkbox<input>prop. - Switch -- controlled toggle:
checked,onChange(checked), optionallabel/disabled. - Avatar --
src(image) orname(renders initials as a fallback),size(number, default 32). - Tabs --
items: {key, label, content}[]; uncontrolled by default (defaultKey) or controlled viaactiveKey/onChange. - Table / Thead / Tbody / Tr / Th / Td -- thin styled wrappers around native table elements, wrapped in a horizontal-scroll container. For sorting/filtering/pagination, use the
data-tablepackage bundle (@tanstack/react-table) instead -- these are for simple static display only.
Button/Card/etc. pick up each app's brand color automatically via the bg-primary/text-primary Tailwind utilities already wired to the --primary CSS variable every generated app's globals.css defines (see template-patches.ts's themedGlobalsCss) -- no extra setup needed. Dark-mode styling uses Tailwind's default dark: variant (prefers-color-scheme).
Consuming this from an app built outside this monorepo
This package ships raw, untranspiled .tsx source (same convention as @sideblend/shared-types) -- no build step to keep it trivial to iterate on. Next.js does not transpile node_modules by default, so any app that installs this from npm needs one line in its next.config.ts:
const nextConfig: NextConfig = {
transpilePackages: ["@viibestack/ui"],
};
Publishing
npm login
cd packages/ui
npm publish
publishConfig.access is already set to "public" in package.json, so this publishes as a free public package under the viibestack npm organization rather than requiring a paid plan.
Bump version in package.json before each subsequent publish (npm rejects re-publishing the same version).