@ah-automation.nl/component-lib
v0.0.105
Published
Reusable React component library built with TypeScript, Tailwind v4, and shadcn/ui.
Readme
component-lib
Reusable React component library built with TypeScript, Tailwind v4, and shadcn/ui.
Development
npm run dev: starts local playground (index.html+src/main.tsx) for manual component testing.npm run build: runs typecheck, emits declaration files, and builds the library bundle.npm run lint: runs ESLint across the codebase.npm run format:check: checks formatting without rewriting files.
Publishing
Package publishing runs from GitHub Actions and publishes publicly to npm.
Before using the workflow, add a repository secret named NPM_TOKEN in GitHub:
- Create an npm access token with publish permission for
@ah-automation.nl/component-lib. - In GitHub, open the repository settings.
- Go to Secrets and variables > Actions.
- Add the token as a repository secret named
NPM_TOKEN.
To publish a new version:
- Open the GitHub repository.
- Go to Actions.
- Select Publish package.
- Click Run workflow.
- Choose
patch,minor, ormajor. - Run the workflow.
The workflow validates the library, bumps package.json and package-lock.json, creates a vX.Y.Z git tag, publishes with npm publish --access public, then pushes the release commit and tag back to main.
Library Output
Build output is generated in dist/:
dist/index.js: ESM library entry.dist/index.d.ts: exported TypeScript types.dist/styles.css: compiled styles for consumers.
Consumer Usage
import { Button } from "component-lib";
import "component-lib/styles.css";
export function Example() {
return <Button>Click me</Button>;
}SidebarNav In Another React Project
import * as React from "react";
import { Home, FolderKanban, Settings, LogOut } from "lucide-react";
import {
Button,
SidebarNav,
type SidebarNavGroup,
type SidebarNavItem,
} from "component-lib";
import "component-lib/styles.css";
const items: SidebarNavItem[] = [
{ label: "Home", route: "/home", icon: Home, order: 0 },
{ label: "Settings", route: "/settings", icon: Settings, order: 20 },
];
const groups: SidebarNavGroup[] = [
{
id: "projects",
label: "Projects",
icon: FolderKanban,
order: 10,
items: [
{ label: "Overview", route: "/projects", badge: "3" },
{ label: "Active", route: "/projects/active" },
],
},
];
export function AppLayout() {
const [activeRoute, setActiveRoute] = React.useState("/home");
return (
<div className="flex min-h-screen">
<SidebarNav
items={items}
groups={groups}
activeRoute={activeRoute}
defaultCollapsed={false}
onItemClick={(item, event) => {
// remove this preventDefault if you want normal anchor navigation
event.preventDefault();
setActiveRoute(item.route);
}}
logo={
<div className="flex items-center gap-2">
<div className="size-7 rounded-md bg-primary" />
<span className="text-sm font-semibold">My Product</span>
</div>
}
footer={
<Button
variant="outline"
className="w-full justify-start group-data-[collapsible=icon]:justify-center"
>
<LogOut />
<span className="group-data-[collapsible=icon]:hidden">Logout</span>
</Button>
}
/>
<main className="min-w-0 flex-1 p-6">
<h1 className="text-xl font-semibold">Active route: {activeRoute}</h1>
</main>
</div>
);
}Notes:
- Import
"component-lib/styles.css"once at app root. defaultCollapsedsets the initial sidebar state.onItemClickis optional. Keephrefbehavior, or intercept and route manually.groupssupports one-level nested routes using collapsibleSidebarGroupsections.ordersupports mixed sorting between flatitemsandgroups(stable fallback preserves input order on ties).
