@brainfish-ai/components
v0.20.4
Published
Brainfish Components
Keywords
Readme
Brainfish Components
Brainfish Components is a React component library that supports both bulk imports and individual component imports (similar to shadcn/ui) for optimal tree-shaking and bundle size optimization.
Installation
npm install @brainfish-ai/components
# or
yarn add @brainfish-ai/componentsUsage
Individual Component Imports (Recommended)
Import only the components you need for optimal bundle size:
// Import individual UI components
import { Button } from '@brainfish-ai/components/ui/button';
import { Dialog } from '@brainfish-ai/components/ui/dialog';
import { Input } from '@brainfish-ai/components/ui/input';
// Import other components
import { ChatSearch } from '@brainfish-ai/components/chat-search';
import { DatePicker } from '@brainfish-ai/components/date-picker';
import { Filter } from '@brainfish-ai/components/filter';
function MyApp() {
return (
<div>
<Button>Click me</Button>
<Input placeholder="Enter text..." />
<DatePicker />
</div>
);
}Bulk Import (Legacy)
Import all components at once (larger bundle size):
import { Button, Dialog, Input, ChatSearch } from '@brainfish-ai/components';Available Individual Imports
UI Components
@brainfish-ai/components/ui/button@brainfish-ai/components/ui/card@brainfish-ai/components/ui/collapsible@brainfish-ai/components/ui/command@brainfish-ai/components/ui/dialog@brainfish-ai/components/ui/dropdown-menu@brainfish-ai/components/ui/input@brainfish-ai/components/ui/label@brainfish-ai/components/ui/popover@brainfish-ai/components/ui/scroll-area@brainfish-ai/components/ui/switch@brainfish-ai/components/ui/textarea@brainfish-ai/components/ui/tooltip
Complex Components
@brainfish-ai/components/chat-search@brainfish-ai/components/combobox@brainfish-ai/components/date-picker@brainfish-ai/components/feedback@brainfish-ai/components/filter@brainfish-ai/components/generating-star@brainfish-ai/components/markdown@brainfish-ai/components/select
Styles
Don't forget to import the CSS:
import '@brainfish-ai/components/styles.css';Development
Getting started
yarn installDeveloping
To start developing run:
yarn startThis will build a version of your library, run the watcher and also run Storybook.
To open Storybook manually open your Browser and navigate to http://localhost:6006.
Start developing your components in src/components folder and update the src/index.js file accordingly.
Always provide an YourComponent.story.tsx file, so your component will show up in Storybook.
Building
Build the library with individual component exports:
yarn build:componentsDevelopment Guide
This section explains the architecture and patterns used in this component library to help new developers get started quickly.
Color System
Our color system is built on CSS custom properties (variables) defined in src/global.css. All variables use the --bfc- prefix (Brainfish Components).
Color Token Scale
Colors follow a 100-1000 scale where lower numbers are lighter and higher numbers are darker:
--bfc-v2-color-blue-100: #e9f2fe; /* lightest */
--bfc-v2-color-blue-500: #4688ec; /* mid-tone */
--bfc-v2-color-blue-1000: #1c2b42; /* darkest */Available Color Palettes
| Palette | CSS Variable Pattern |
|-----------|-----------------------------------|
| Mono | --bfc-v2-color-mono-{100-1000} |
| Red | --bfc-v2-color-red-{100-1000} |
| Orange | --bfc-v2-color-orange-{100-1000}|
| Yellow | --bfc-v2-color-yellow-{100-1000}|
| Lime | --bfc-v2-color-lime-{100-1000} |
| Green | --bfc-v2-color-green-{100-1000} |
| Blue | --bfc-v2-color-blue-{100-1000} |
| Teal | --bfc-v2-color-teal-{100-1000} |
| Purple | --bfc-v2-color-purple-{100-1000}|
| Magenta | --bfc-v2-color-magenta-{100-1000}|
Semantic Color Tokens
Instead of using raw color values, use semantic tokens that adapt to themes:
| Token | Purpose |
|--------------------------|--------------------------------|
| --bfc-primary | Primary brand color |
| --bfc-background | Page background |
| --bfc-foreground | Primary text color |
| --bfc-muted | Subdued backgrounds |
| --bfc-muted-foreground | Subdued text |
| --bfc-border | Border color |
| --bfc-destructive-bg | Error/danger backgrounds |
| --bfc-success-bg | Success state backgrounds |
Dark Mode
Dark mode is activated by adding the .dark class to the element. The color scale is automatically inverted (100 becomes the darkest, 1000 becomes the lightest), ensuring consistent contrast in both themes.
<!-- Light mode (default) -->
<html>...</html>
<!-- Dark mode -->
<html class="dark">...</html>Tailwind CSS Integration
We use Tailwind CSS with a custom preset that maps our color system to Tailwind utilities.
Using the Tailwind Preset
Consumers of this library can import our Tailwind preset to use the same design tokens:
// tailwind.config.js
module.exports = {
presets: [require('@brainfish-ai/components/tailwind')],
// ... your config
};Semantic Color Classes
Use semantic Tailwind classes instead of raw colors:
// Good - uses semantic colors that adapt to themes
<div className="bg-primary text-foreground border-border" />
<div className="bg-destructive text-destructive" />
<div className="bg-muted text-muted-foreground" />
// Bad - hardcoded colors won't adapt to dark mode
<div className="bg-[#a3e635] text-[#171717]" />Typography Utilities
Custom typography classes are available for consistent text styles:
| Class | Font Size | Use Case |
|----------------|-----------|---------------------|
| .heading-xxl | 2rem | Page titles |
| .heading-xl | 1.75rem | Section headers |
| .heading-lg | 1.5rem | Card headers |
| .heading-m | 1.25rem | Subsections |
| .heading-sm | 1rem | Small headers |
| .paragraph-lg| 1rem | Body text |
| .paragraph-md| 0.875rem | Default text |
| .paragraph-sm| 0.75rem | Captions, labels |
The cn() Utility
Use cn() from @/lib/utils to merge Tailwind classes safely:
import { cn } from '@/lib/utils';
// Merges classes and handles conflicts properly
<div className={cn('bg-primary p-4', isActive && 'bg-accent', className)} />Component Patterns (shadcn/ui)
Our UI components follow shadcn/ui patterns and conventions.
Component Location
- Base UI components:
src/components/ui/ - Complex/composite components:
src/components/
Component Structure
Components use class-variance-authority (CVA) for variant management:
import * as React from 'react';
import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from '@/lib/utils';
// Define variants with CVA
const buttonVariants = cva(
'inline-flex items-center justify-center rounded-md text-sm font-medium',
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground',
destructive: 'bg-destructive text-destructive-foreground',
outline: 'border border-input bg-background',
},
size: {
default: 'h-9 px-4 py-2',
sm: 'h-8 px-3 text-sm',
lg: 'h-10 px-8',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
}
);
// Component with forwarded ref
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, ...props }, ref) => (
<button
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
)
);
Button.displayName = 'Button';
export { Button, buttonVariants };Key Conventions
- Always use semantic colors - Never use raw hex values in components
- Forward refs - All components should forward refs for flexibility
- Use
cn()for className - Always merge with incoming className prop - Export variants - Export the CVA variants for reuse
- Set displayName - Always set
displayNamefor better debugging
Storybook Requirements
Every component MUST have an accompanying Storybook story file.
Why Stories Matter
- Enable independent component testing and development
- Serve as living documentation for the component API
- Allow visual regression testing
- Help designers and developers collaborate
Story File Convention
For a component Button.tsx, create Button.stories.tsx in the same directory:
src/components/ui/
├── button.tsx
├── button.stories.tsx <-- Required!
└── button.test.tsx <-- Optional unit testsStory Structure
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './button';
const meta: Meta<typeof Button> = {
title: 'UI/Button',
component: Button,
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<typeof Button>;
// Show all variants
export const Default: Story = {
args: { children: 'Click me' },
};
export const Destructive: Story = {
args: { variant: 'destructive', children: 'Delete' },
};
export const AllSizes: Story = {
render: () => (
<div className="flex gap-4">
<Button size="sm">Small</Button>
<Button size="default">Default</Button>
<Button size="lg">Large</Button>
</div>
),
};Running Storybook
yarn storybookThen open http://localhost:6006 in your browser.
Linting and Code formating for Typescript
Linting and code formating is done via ESLint and Prettier using eslint-plugin-react and
eslint-config-prettier.
You can modify linting rules by overriding them in the .eslintrc.cjs file.
yarn lintor (if automatic fixing is possible)
yarn lint:fixTesting
Testing is done with Vitest and @testing-library/react
You can refer to Button.test.js as an example.
yarn testPublishing your library to NPM
To release your library to NPM or your private Registry, make sure you have an active account at NPM, your .npmrc file is correctly setup and the registry url at publishConfig in package.json file is set to your repository url, then:
yarn releaseStorybook
For custom layouts, styling and more information about Storybook, please refer to Storybook documentation.
Deploy Storybook to GitHub Pages
Make sure the homepage url in package.json file is set to your githup pages url, then:
yarn deployScripts
yarn start: Only serves Storybook.yarn build: Builds your library (build can be found indistfolder).yarn storybook:build: Builds the static Storybook in case you want to deploy it.yarn test: Runs the tests.yarn test:coverage: Runs the test and shows the coverage.yarn lint: Runs the linter, Typescript typecheck and stylelint.yarn lint:fix: Runs the linter, Typescript typecheck and stylelint and fixes automatic fixable issues.yarn eslint: Runs only the JavaScript linter.yarn eslint:fix: Runs only the JavaScript linter and fixes automatic fixable issues.yarn stylelint: Runs only the style linter.yarn stylelint:fix: Runs only the style linter and fixes automatic fixable issues.yarn check-types: Runs typescript type checker.yarn ci: Runs Linting, tests and type checker all together.yarn release: Publishes your Library on NPM or your private Registry (depending on your config in your.npmrcfile).yarn storybook: Same as yarn start, to serve storybook.yarn storybook:build: Generates the build for storybook instorybook-staticfolder, that can be deployed wherever you need.yarn storybook:deploy: Builds and deploys Storybook to GitHub Pages.
