@chainberry/ui-components
v1.0.58
Published
Chainberry navigation UI components — React + Tailwind. Canonical source lives in ../../react-app/src/components; this package re-exports, builds, and publishes them.
Readme
@chainberry/ui-components
Chainberry navigation UI components — React + Tailwind. Ships a self-contained stylesheet, so consumers need no Tailwind setup.
The components are authored and maintained in the react-app/ package (rendered
in its Storybook). This package is a thin publish barrel that re-exports,
builds, and versions them — react-app/src/components is the single source of
truth.
Install
npm install @chainberry/ui-componentsreact and react-dom are peer dependencies (React 18 or 19).
Usage
import { NavDrawer } from "@chainberry/ui-components";
import "@chainberry/ui-components/styles.css"; // once, anywhere at your app root
export function Sidebar() {
return (
// the wrapper is required — see below
<div className="chainberry">
<NavDrawer
preset="primary" // "primary" (trimmed) | "full"
activeId="dashboard"
onNavigate={(id) => console.log("navigate →", id)}
/>
</div>
);
}The chainberry wrapper
Required. The stylesheet is scoped: every token, reset and utility applies
only inside an element carrying the chainberry class. Without the wrapper
the components render unstyled.
It must be an ancestor, not the component itself — rules compile to
.chainberry :is(.bg-primary), a descendant selector. <NavDrawer
className="chainberry" /> will not work. One wrapper high in the tree is
enough; nesting them is harmless.
Why scoped: this package and your app both run Tailwind 3.4.3, so both generate
.bg-primary, .text-foreground and friends. Unscoped, whichever stylesheet
loaded last would define those classes for the whole page — ours would restyle
your components, or yours would strip ours. The scope raises our specificity to
(0,2,0) so our rules win inside the wrapper and are inert outside it. A useful
consequence: import order does not matter.
Content rendered through a portal (Dialog, SidePanel, DropdownMenu,
Popover, Tooltip) mounts on document.body, outside your wrapper. Those
components re-apply the scope internally, so they work with no extra setup.
Theming
Tokens are CSS variables set on .chainberry. For the dark palette add .dark
to an ancestor (e.g. <html class="dark">) — .dark .chainberry and
.chainberry.dark both resolve.
Because the tokens are scoped, they cannot collide with your app's variables
even if you use the same names (--primary, --background, …). To restyle the
components, redefine the tokens on your wrapper:
.chainberry { --primary: oklch(0.3 0.1 260); }About the stylesheet
styles.css contains the design tokens and the utility classes the components
use. It does not ship Tailwind Preflight — the reset cannot be scoped, and a
Tailwind app already has its own via @tailwind base. An app with no Tailwind
and no reset of its own may see minor differences from the design (default
margins on headings and lists, button font inheritance).
The Geist webfont is not bundled; --font-sans falls back to the system sans
stack (supply Geist yourself to match the design).
Exports
- Organism:
NavDrawer - Molecules:
NavItem,NavGroup - Atoms:
Badge,NavIcon,NavLabel,Logo,SectionHeading - shadcn UI:
Button,buttonVariants - Data/helpers:
PRIMARY_NAV,FULL_NAV,NAV_PRESETS,NAV_ITEMS,findNavItem,ICONS,ICON_NAMES - Types:
NavItemConfig,NavGroupConfig,NavPreset,BadgeVariant,NavItemProps,IconName
Custom navigation:
import { NavDrawer, type NavGroupConfig } from "@chainberry/ui-components";
const config: NavGroupConfig[] = [
{ label: "Overview", items: [{ id: "home", label: "Home", icon: "grid" }] },
];
<NavDrawer config={config} activeId="home" />;1.0.1
A non-breaking patch over 1.0.0 — the components are now sourced from the
canonical react-app build:
- Adds
Button/buttonVariants(pullsradix-ui+class-variance-authority). - Adds
NAV_ITEMSandfindNavItemhelpers. NavBadgewas renamed toBadge(NavBadgeVariant→BadgeVariant). The old names remain exported as deprecated aliases (NavBadge,NavBadgeVariant,NavBadgeProps), so 1.0.0 code keeps working — migrate toBadgewhen convenient; the aliases go away in the next major.styles.cssstill ships Preflight, matching 1.0.0.
Develop
The build consumes the canonical components from ../../react-app/src via the
@ alias — no code lives in this package except the barrel and the stylesheet.
npm install
npm run build # dist/ (ESM + CJS + .d.ts + styles.css)
npm run build:js # ESM + CJS + bundled types only
npm run build:css # dist/styles.css only
npm run typecheckTo iterate on a component, edit it in react-app/src/components (its Storybook
shows it live), then rebuild here.
Publish
npm login # must be a member of the @chainberry npm org
npm publish # runs the build via prepublishOnly; access: public