API Reference
Note: This is a partial API reference showing the most commonly used props. For complete type definitions, see the TypeScript types exported from each component. All components extend standard HTML attributes where applicable.
Complete API documentation for all Nostromo UI components.
Tip: Import components from
@jarllyng/nostromoor@jarllyng/nostromoto get full TypeScript support and autocomplete.
Core Components
Button
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?:
| "default"
| "destructive"
| "outline"
| "secondary"
| "ghost"
| "link"
| "subtle";
size?: "default" | "sm" | "lg" | "xl" | "icon";
state?: "default" | "loading" | "success" | "error";
disabled?: boolean;
loading?: boolean;
loadingText?: string;
children: React.ReactNode;
className?: string;
}Input
interface InputProps extends Omit<
React.InputHTMLAttributes<HTMLInputElement>,
"size"
> {
variant?: "default" | "error" | "success" | "subtle";
inputSize?: "sm" | "default" | "lg";
error?: boolean;
success?: boolean;
helperText?: string;
label?: string;
className?: string;
// ... all standard HTML input attributes
}Dialog
interface DialogProps {
open?: boolean;
onOpenChange?: (open: boolean) => void;
children: React.ReactNode;
className?: string;
}
interface DialogContentProps {
children: React.ReactNode;
className?: string;
}
interface DialogHeaderProps {
children: React.ReactNode;
className?: string;
}
interface DialogTitleProps {
children: React.ReactNode;
className?: string;
}
interface DialogDescriptionProps {
children: React.ReactNode;
className?: string;
}Card
interface CardProps {
children: React.ReactNode;
className?: string;
}
interface CardHeaderProps {
children: React.ReactNode;
className?: string;
}
interface CardTitleProps {
children: React.ReactNode;
className?: string;
}
interface CardDescriptionProps {
children: React.ReactNode;
className?: string;
}
interface CardContentProps {
children: React.ReactNode;
className?: string;
}
interface CardFooterProps {
children: React.ReactNode;
className?: string;
}Badge
interface BadgeProps {
variant?: "default" | "secondary" | "destructive" | "outline";
size?: "default" | "sm" | "lg";
children: React.ReactNode;
className?: string;
}Alert
interface AlertProps {
variant?: "default" | "destructive";
children: React.ReactNode;
className?: string;
}
interface AlertTitleProps {
children: React.ReactNode;
className?: string;
}
interface AlertDescriptionProps {
children: React.ReactNode;
className?: string;
}Avatar
interface AvatarProps {
src?: string;
alt?: string;
fallback?: string;
size?: "sm" | "md" | "lg";
className?: string;
}Checkbox
interface CheckboxProps {
checked?: boolean;
onCheckedChange?: (checked: boolean) => void;
disabled?: boolean;
required?: boolean;
id?: string;
name?: string;
value?: string;
className?: string;
}Icon
interface IconProps {
name: IconName; // See iconNames export for available icons (~170 icons)
size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl";
weight?: "thin" | "light" | "regular" | "bold" | "fill" | "duotone";
color?:
| "current"
| "primary"
| "secondary"
| "success"
| "warning"
| "error"
| "muted";
className?: string;
// ... all standard SVG attributes
}
// Note: For icons not in iconMap, import directly from 'phosphor-react'
// Example: import { CustomIcon } from 'phosphor-react'Label
interface LabelProps {
htmlFor?: string;
children: React.ReactNode;
className?: string;
}Pagination
interface PaginationProps {
currentPage: number;
totalPages: number;
onPageChange: (page: number) => void;
showFirstLast?: boolean;
showPrevNext?: boolean;
className?: string;
}Progress
interface ProgressProps {
value?: number;
max?: number;
className?: string;
}Select
interface SelectProps {
value?: string;
onValueChange?: (value: string) => void;
disabled?: boolean;
children: React.ReactNode;
className?: string;
}
interface SelectTriggerProps {
children: React.ReactNode;
className?: string;
}
interface SelectValueProps {
placeholder?: string;
className?: string;
}
interface SelectContentProps {
children: React.ReactNode;
className?: string;
}
interface SelectItemProps {
value: string;
children: React.ReactNode;
className?: string;
}Separator
interface SeparatorProps {
orientation?: "horizontal" | "vertical";
className?: string;
}Skeleton
interface SkeletonProps {
className?: string;
}Switch
interface SwitchProps {
checked?: boolean;
onCheckedChange?: (checked: boolean) => void;
disabled?: boolean;
required?: boolean;
id?: string;
name?: string;
value?: string;
className?: string;
}Table
interface TableProps {
children: React.ReactNode;
className?: string;
}
interface TableHeaderProps {
children: React.ReactNode;
className?: string;
}
interface TableBodyProps {
children: React.ReactNode;
className?: string;
}
interface TableRowProps {
children: React.ReactNode;
className?: string;
}
interface TableHeadProps {
children: React.ReactNode;
className?: string;
}
interface TableCellProps {
children: React.ReactNode;
className?: string;
}DataTable
interface DataTableProps<T = Record<string, unknown>> {
data: T[];
columns: TableColumn<T>[];
searchable?: boolean;
filterable?: boolean;
filters?: ColumnFilter<T>[];
showPagination?: boolean;
defaultPageSize?: number;
onSearch?: (searchTerm: string, filteredData: T[]) => void;
onFilter?: (filters: Record<string, unknown>, filteredData: T[]) => void;
className?: string;
}
interface ColumnFilter<T = Record<string, unknown>> {
key: string;
type: "text" | "select" | "number" | "date" | "boolean";
options?: Array<{ label: string; value: string | number }>;
placeholder?: string;
filterFn?: (value: unknown, record: T) => boolean;
}Calendar
interface CalendarProps {
mode?: "single" | "range" | "multiple";
value?: Date | Date[] | { from?: Date; to?: Date };
defaultValue?: Date | Date[] | { from?: Date; to?: Date };
onChange?: (
value: Date | Date[] | { from?: Date; to?: Date } | undefined,
) => void;
minDate?: Date;
maxDate?: Date;
disabledDates?: Date[];
disabledDays?: number[];
locale?: string;
placeholder?: string;
label?: string;
error?: boolean;
helperText?: string;
className?: string;
}Charts
interface ChartProps {
type: "line" | "bar" | "pie" | "area";
data: ChartDataPoint[];
dataKeys: string[];
xAxisKey?: string;
colors?: (string | undefined)[];
showGrid?: boolean;
showLegend?: boolean;
showTooltip?: boolean;
title?: string;
description?: string;
className?: string;
height?: number;
ariaLabel?: string;
ariaLabelledBy?: string;
strokeWidth?: number;
fillOpacity?: number;
}
interface ChartDataPoint {
name: string;
[key: string]: string | number;
}Tabs
interface TabsProps {
defaultValue?: string;
value?: string;
onValueChange?: (value: string) => void;
children: React.ReactNode;
className?: string;
}
interface TabsListProps {
children: React.ReactNode;
className?: string;
}
interface TabsTriggerProps {
value: string;
children: React.ReactNode;
className?: string;
}
interface TabsContentProps {
value: string;
children: React.ReactNode;
className?: string;
}Textarea
interface TextareaProps {
placeholder?: string;
disabled?: boolean;
value?: string;
onChange?: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
className?: string;
id?: string;
name?: string;
required?: boolean;
rows?: number;
}Toast
interface ToastProps {
title?: string;
description?: string;
variant?: "default" | "destructive";
action?: React.ReactNode;
children?: React.ReactNode;
className?: string;
}Tooltip
interface TooltipProps {
children: React.ReactNode;
content: React.ReactNode;
side?: "top" | "right" | "bottom" | "left";
align?: "start" | "center" | "end";
className?: string;
}Marketing Components
Hero
interface HeroProps {
title: string;
subtitle?: string;
cta?: React.ReactNode;
size?: "sm" | "md" | "lg" | "xl";
variant?: "default" | "muted" | "accent";
contentAlign?: "left" | "center" | "right";
titleSize?: "sm" | "md" | "lg" | "xl";
subtitleSize?: "sm" | "md" | "lg";
backgroundImage?: string;
overlay?: boolean;
className?: string;
}Features
interface FeaturesProps {
features: Array<{
id: string;
title: string;
description: string;
icon?: React.ReactNode;
iconVariant?:
"default" | "accent" | "muted" | "success" | "warning" | "error";
}>;
title?: string;
subtitle?: string;
columns?: 1 | 2 | 3 | 4;
variant?: "default" | "muted" | "accent";
cardVariant?: "default" | "accent" | "muted";
centered?: boolean;
className?: string;
}Gallery
interface GalleryProps {
images: Array<{
src: string;
alt: string;
title?: string;
description?: string;
}>;
className?: string;
}LogoWall
interface LogoWallProps {
logos: Array<{
src: string;
alt: string;
href?: string;
}>;
className?: string;
}Pricing
interface PricingProps {
plans: Array<{
id: string;
name: string;
description?: string;
price: {
monthly: number;
yearly?: number;
};
currency?: string;
period?: string;
features: Array<{
id: string;
name: string;
included: boolean;
}>;
cta: {
text: string;
href?: string;
onClick?: () => void;
};
badge?: {
text: string;
variant?: "default" | "accent" | "success" | "warning";
};
popular?: boolean;
}>;
title?: string;
subtitle?: string;
columns?: 1 | 2 | 3 | 4;
variant?: "default" | "muted" | "accent";
showYearly?: boolean;
onToggleBilling?: (yearly: boolean) => void;
className?: string;
}Testimonials
interface TestimonialsProps {
testimonials: Array<{
id: string;
name: string;
role: string;
company?: string;
content: string;
avatar?: string;
rating?: number;
}>;
title?: string;
subtitle?: string;
columns?: 1 | 2 | 3 | 4;
variant?: "default" | "muted" | "accent";
cardVariant?: "default" | "accent" | "muted";
showRatings?: boolean;
className?: string;
}TypeScript Support
All components are fully typed with TypeScript. Import types directly:
import type { ButtonProps, InputProps } from "@jarllyng/nostromo";Common Patterns
Form Integration
import { useForm } from "react-hook-form";
import { Button, Input, Label } from "@jarllyng/nostromo";
function ContactForm() {
// The generic is what types `register` and the submitted values. Without it
// both fall back to `FieldValues` and a typed handler no longer fits.
const { register, handleSubmit } = useForm<{ email: string }>();
// Named here rather than left to the reader: `handleSubmit` wants a function,
// and the version of this example that referred to a bare `onSubmit` threw on
// paste.
const onSubmit = (values: { email: string }) => {
console.log(values);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Label htmlFor="email">Email</Label>
<Input {...register("email")} id="email" type="email" />
<Button type="submit">Submit</Button>
</form>
);
}State Management
import { useState } from "react";
import { Dialog, DialogContent, DialogTrigger } from "@jarllyng/nostromo";
function MyDialog() {
const [open, setOpen] = useState(false);
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger>Open</DialogTrigger>
<DialogContent>
<p>Dialog content</p>
</DialogContent>
</Dialog>
);
}Accessibility
All components follow WCAG 2.1 AA guidelines:
- Keyboard Navigation - Full keyboard support
- Screen Readers - Proper ARIA attributes
- Focus Management - Visible focus indicators
- Color Contrast - Meets accessibility standards
Performance
- Tree Shaking - Import only what you need
- Bundle Size - Optimized for minimal impact
- SSR Compatible - Works with Next.js, Remix, etc.
- No Runtime Dependencies - Zero runtime overhead
Last updated on