React Components
Core UI components for building MCP applications. Built on shadcn/ui design system with MCP-specific enhancements.
Installation
Import styles in your app:
import '@leanmcp/ui/styles.css';
Core Components
Button component with multiple variants and loading state.
import { Button } from '@leanmcp/ui';
function MyComponent() {
return (
<Button variant="primary" onClick={handleClick}>
Click Me
</Button>
);
}
Props
Button style variantOptions: primary | secondary | ghost | destructive | outline
Button sizeOptions: sm | md | lg | icon
Show loading spinner and disable button
Render as child component using Radix Slot
Icon to display on the left side
Icon to display on the right side
Examples
// Loading state
<Button loading>Loading...</Button>
// With icons
<Button leftIcon={<SearchIcon />}>Search</Button>
// Variants
<Button variant="destructive">Delete</Button>
<Button variant="ghost">Cancel</Button>
Card
Card container component with header, content, and footer sections.
import { Card, CardHeader, CardContent, CardFooter } from '@leanmcp/ui';
function MyComponent() {
return (
<Card variant="elevated">
<CardHeader title="Settings" description="Manage your preferences" />
<CardContent>
{/* Content */}
</CardContent>
<CardFooter>
<Button>Save</Button>
</CardFooter>
</Card>
);
}
Card Props
Card style variantOptions: default | outline | elevated
Card padding sizeOptions: none | sm | md | lg
Enable hover effects for clickable cards
Right-side action element (e.g., button)
Input component with label, validation, and icon support.
import { Input } from '@leanmcp/ui';
function MyComponent() {
return (
<Input
label="Email"
type="email"
placeholder="Enter your email"
error={errors.email}
fullWidth
/>
);
}
Props
Helper text displayed below input
Error message (displays in red)
Input sizeOptions: sm | md | lg
Element to display on the left (e.g., icon)
Element to display on the right (e.g., icon)
Expand to full width of container
Examples
// With icon
<Input
leftElement={<SearchIcon />}
placeholder="Search..."
/>
// With validation
<Input
label="Username"
value={username}
error={username.length < 3 ? 'Too short' : undefined}
/>
Select
Dropdown select component.
import { Select } from '@leanmcp/ui';
function MyComponent() {
return (
<Select
value={value}
onChange={setValue}
options={[
{ value: 'opt1', label: 'Option 1' },
{ value: 'opt2', label: 'Option 2' },
]}
/>
);
}
Props
Array of optionsinterface SelectOption {
value: string;
label: string;
disabled?: boolean;
}
placeholder
string
default:"Select..."
Placeholder text when no value selected
Alert
Inline feedback messages with multiple variants.
import { Alert } from '@leanmcp/ui';
function MyComponent() {
return (
<Alert variant="success" title="Success">
Your changes have been saved.
</Alert>
);
}
Props
variant
AlertVariant
default:"info"
Alert style variantOptions: info | success | warning | error
Alert content/description
Dismiss handler. Shows close button if provided.
Examples
<Alert variant="error" title="Error" onDismiss={handleDismiss}>
Failed to save changes. Please try again.
</Alert>
<Alert variant="warning">
This action cannot be undone.
</Alert>
Layout Components
Modal
Dialog/modal component built on Radix UI.
import { Modal, Button } from '@leanmcp/ui';
function MyComponent() {
const [open, setOpen] = useState(false);
return (
<Modal
open={open}
onOpenChange={setOpen}
title="Confirm Delete"
description="This action cannot be undone."
trigger={<Button>Open Modal</Button>}
>
<Button onClick={() => setOpen(false)}>Cancel</Button>
<Button variant="destructive" onClick={handleDelete}>Delete</Button>
</Modal>
);
}
Props
Uncontrolled default open state
Open state change handler
Element that triggers the modal (e.g., button)
Data Components
DataGrid
Sortable, filterable data table for displaying tool results.
import { DataGrid } from '@leanmcp/ui';
import { useTool } from '@leanmcp/ui';
function MyComponent() {
const { result } = useTool<{ items: Item[] }>('get-items');
return (
<DataGrid
data={result?.items ?? []}
columns={[
{ key: 'name', header: 'Name', sortable: true },
{ key: 'price', header: 'Price', cell: (v) => `$${v}` },
{ key: 'status', header: 'Status' },
]}
searchable
onRowClick={(row) => console.log(row)}
/>
);
}
Props
Array of data objects to display
columns
DataGridColumn<T>[]
required
Column definitionsinterface DataGridColumn<T> {
key: keyof T | string;
header: string;
cell?: (value: unknown, row: T) => ReactNode;
sortable?: boolean;
width?: number | string;
}
Enable global search functionality
searchPlaceholder
string
default:"Search..."
Search input placeholder
Message to display when data is empty
Examples
// Custom cell renderer
<DataGrid
data={users}
columns={[
{ key: 'name', header: 'Name' },
{
key: 'email',
header: 'Email',
cell: (value) => <a href={`mailto:${value}`}>{value}</a>
},
{
key: 'role',
header: 'Role',
sortable: false,
width: 100
}
]}
/>
Type Reference
SelectOption
interface SelectOption {
value: string;
label: string;
disabled?: boolean;
}
AlertVariant
type AlertVariant = 'info' | 'success' | 'warning' | 'error';
DataGridColumn
interface DataGridColumn<T> {
key: keyof T | string;
header: string;
cell?: (value: unknown, row: T) => ReactNode;
sortable?: boolean;
width?: number | string;
}
See Also