@fnd-platform/component-library
v1.0.0-alpha.7
Published
Projen project class for generating Storybook-based component library packages in fnd-platform
Maintainers
Readme
@fnd-platform/component-library
Projen project class for generating Storybook-based component library packages with React and Tailwind CSS in fnd-platform monorepos.
Installation
npm install -D @fnd-platform/component-library
# or
pnpm add -D @fnd-platform/component-libraryQuick Start
Add a component library package to your monorepo in .projenrc.ts:
import { FndMonorepoProject } from '@fnd-platform/core';
import { FndComponentLibraryProject } from '@fnd-platform/component-library';
const monorepo = new FndMonorepoProject({
name: 'my-app',
defaultReleaseBranch: 'main',
});
const ui = new FndComponentLibraryProject({
parent: monorepo,
name: 'ui',
outdir: 'packages/ui',
storybookPort: 6006,
});
monorepo.synth();Or use the CLI:
fnd add component-library --name=uiConfiguration Options
| Option | Type | Default | Description |
| ------------------ | -------------------- | ----------------- | ------------------------- |
| parent | FndMonorepoProject | required | Parent monorepo |
| name | string | required | Package name |
| outdir | string | packages/{name} | Output directory |
| storybookVersion | string | '^8.0.0' | Storybook version |
| storybookPort | number | 6006 | Storybook dev server port |
What Gets Generated
packages/ui/
├── src/
│ ├── components/
│ │ ├── Button/
│ │ │ ├── Button.tsx
│ │ │ ├── Button.stories.tsx
│ │ │ ├── Button.test.tsx
│ │ │ └── index.ts
│ │ └── index.ts
│ ├── styles/
│ │ └── globals.css
│ └── index.ts
├── .storybook/
│ ├── main.ts
│ ├── preview.ts
│ └── preview-head.html
├── package.json
├── tailwind.config.js
├── tsconfig.json
├── tsconfig.build.json
└── vitest.config.tsFeatures
- Storybook 8.x - Latest Storybook with React and Vite
- React Components - TypeScript React components
- Tailwind CSS - Utility-first styling
- Vitest - Fast unit testing
- TypeScript - Full type safety
- Auto-generated Stories - Component story templates
Examples
Creating a Component
// src/components/Card/Card.tsx
import { type ReactNode } from 'react';
import { cn } from '../../lib/utils';
export interface CardProps {
children: ReactNode;
className?: string;
variant?: 'default' | 'outlined';
}
export function Card({ children, className, variant = 'default' }: CardProps) {
return (
<div
className={cn(
'rounded-lg p-4',
variant === 'default' && 'bg-white shadow',
variant === 'outlined' && 'border border-gray-200',
className
)}
>
{children}
</div>
);
}Writing Stories
// src/components/Card/Card.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Card } from './Card';
const meta: Meta<typeof Card> = {
title: 'Components/Card',
component: Card,
tags: ['autodocs'],
argTypes: {
variant: {
control: 'select',
options: ['default', 'outlined'],
},
},
};
export default meta;
type Story = StoryObj<typeof Card>;
export const Default: Story = {
args: {
children: 'Card content',
},
};
export const Outlined: Story = {
args: {
children: 'Outlined card content',
variant: 'outlined',
},
};Writing Tests
// src/components/Card/Card.test.tsx
import { render, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { Card } from './Card';
describe('Card', () => {
it('renders children', () => {
render(<Card>Hello</Card>);
expect(screen.getByText('Hello')).toBeInTheDocument();
});
it('applies variant class', () => {
const { container } = render(<Card variant="outlined">Content</Card>);
expect(container.firstChild).toHaveClass('border');
});
});Exporting Components
// src/components/index.ts
export { Button } from './Button';
export type { ButtonProps } from './Button';
export { Card } from './Card';
export type { CardProps } from './Card';
// src/index.ts
export * from './components';Development
# Start Storybook development server
cd packages/ui
pnpm storybook
# Build Storybook for production
pnpm build-storybook
# Run tests
pnpm test
# Build the library
pnpm build
# Type check
pnpm typecheckUsing in Other Packages
Import components in your frontend or CMS packages:
// In packages/frontend/app/routes/_index.tsx
import { Button, Card } from '@my-app/ui';
export default function Home() {
return (
<Card>
<h1>Welcome</h1>
<Button>Get Started</Button>
</Card>
);
}API Reference
See the full API documentation for detailed type definitions and examples.
Project Class
FndComponentLibraryProject- Projen project class for component library packages
Types
import type { FndComponentLibraryProjectOptions } from '@fnd-platform/component-library';Requirements
- Node.js 20+
- pnpm 8+
- @fnd-platform/core
Related
- @fnd-platform/core - Core Projen project classes
- @fnd-platform/frontend - Frontend package using components
- @fnd-platform/cms - CMS package using components
- Storybook Documentation
License
MIT
