Beautiful and modern React UI library with comprehensive components, theming, and accessibility support.
npx @tessl/cli install tessl/npm-nextui-org--react@2.6.0NextUI is a beautiful and modern React UI library that provides a comprehensive set of accessible components, advanced theming capabilities, and seamless integration with modern React development workflows. Built on top of React Aria and Tailwind CSS, it offers both beautiful design and robust functionality out of the box.
npm install @nextui-org/reactimport { NextUIProvider, Button, Input, Card } from "@nextui-org/react";For CommonJS:
const { NextUIProvider, Button, Input, Card } = require("@nextui-org/react");import React from "react";
import { NextUIProvider, Button, Card, CardBody, Input } from "@nextui-org/react";
function App() {
return (
<NextUIProvider>
<div className="p-8 space-y-4">
<Card>
<CardBody>
<h1 className="text-2xl font-bold mb-4">Welcome to NextUI</h1>
<Input
label="Email"
placeholder="Enter your email"
type="email"
className="mb-4"
/>
<Button color="primary">
Get Started
</Button>
</CardBody>
</Card>
</div>
</NextUIProvider>
);
}
export default App;NextUI is built around several key architectural principles:
NextUIProvider manages global configuration including themes, localization, and routingNextUI's foundation includes the provider system, theme configuration, and styling utilities that power the entire library.
// Provider component
interface NextUIProviderProps {
children: React.ReactNode;
locale?: string;
theme?: "light" | "dark";
themes?: ConfigThemes;
defaultTheme?: string;
disableAnimation?: boolean;
disableRipple?: boolean;
skipFramerMotionAnimations?: boolean;
validationBehavior?: "aria" | "native";
navigate?: (path: string) => void;
}
function NextUIProvider(props: NextUIProviderProps): JSX.Element;
// Theme utilities
function tv(config: TVConfig): (...args: any[]) => string;
function cn(...classes: ClassValue[]): string;Structural components for organizing content and creating visual hierarchy.
interface CardProps {
children?: React.ReactNode;
shadow?: "none" | "sm" | "md" | "lg";
radius?: "none" | "sm" | "md" | "lg";
fullWidth?: boolean;
isHoverable?: boolean;
isPressable?: boolean;
isBlurred?: boolean;
isDisabled?: boolean;
disableAnimation?: boolean;
disableRipple?: boolean;
allowTextSelectionOnPress?: boolean;
className?: string;
classNames?: SlotsToClasses<CardSlots>;
}
interface SpacerProps {
x?: number;
y?: number;
className?: string;
}
interface DividerProps {
orientation?: "horizontal" | "vertical";
className?: string;
}Components for user actions and interactions including buttons and toggles with consistent styling and accessibility.
interface ButtonProps {
children?: React.ReactNode;
variant?: "solid" | "bordered" | "light" | "flat" | "faded" | "shadow" | "ghost";
size?: "sm" | "md" | "lg";
color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
radius?: "none" | "sm" | "md" | "lg" | "full";
fullWidth?: boolean;
isDisabled?: boolean;
isLoading?: boolean;
isIconOnly?: boolean;
startContent?: React.ReactNode;
endContent?: React.ReactNode;
spinner?: React.ReactNode;
spinnerPlacement?: "start" | "end";
disableRipple?: boolean;
disableAnimation?: boolean;
onPress?: (e: PressEvent) => void;
className?: string;
classNames?: SlotsToClasses<ButtonSlots>;
}
interface ButtonGroupProps {
children: React.ReactNode;
size?: "sm" | "md" | "lg";
color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
variant?: "solid" | "bordered" | "light" | "flat" | "faded" | "shadow" | "ghost";
radius?: "none" | "sm" | "md" | "lg" | "full";
fullWidth?: boolean;
isDisabled?: boolean;
className?: string;
classNames?: SlotsToClasses<ButtonGroupSlots>;
}Components for navigation, routing, and organizing hierarchical content.
interface NavbarProps {
children?: React.ReactNode;
height?: string | number;
maxWidth?: "sm" | "md" | "lg" | "xl" | "2xl" | "full";
position?: "static" | "sticky";
isBordered?: boolean;
isBlurred?: boolean;
shouldHideOnScroll?: boolean;
className?: string;
classNames?: SlotsToClasses<NavbarSlots>;
}
interface BreadcrumbsProps {
children: React.ReactNode;
separator?: React.ReactNode;
size?: "sm" | "md" | "lg";
radius?: "none" | "sm" | "md" | "lg" | "full";
variant?: "solid" | "bordered" | "light";
color?: "foreground" | "primary" | "secondary" | "success" | "warning" | "danger";
underline?: "none" | "hover" | "always" | "active" | "focus";
hideSeparator?: boolean;
isDisabled?: boolean;
disableAnimation?: boolean;
className?: string;
classNames?: SlotsToClasses<BreadcrumbsSlots>;
}Form controls and input elements with validation and accessibility support.
interface InputProps {
children?: React.ReactNode;
label?: React.ReactNode;
value?: string;
defaultValue?: string;
placeholder?: string;
description?: React.ReactNode;
errorMessage?: React.ReactNode | ((v: ValidationResult) => React.ReactNode);
validate?: (value: string) => ValidationError | true | null | undefined;
validationBehavior?: "aria" | "native";
validationState?: "valid" | "invalid";
isRequired?: boolean;
isReadOnly?: boolean;
isDisabled?: boolean;
isInvalid?: boolean;
baseRef?: React.RefObject<HTMLDivElement>;
hasHelper?: boolean;
size?: "sm" | "md" | "lg";
radius?: "none" | "sm" | "md" | "lg" | "full";
variant?: "flat" | "bordered" | "underlined" | "faded";
color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
labelPlacement?: "inside" | "outside" | "outside-left";
fullWidth?: boolean;
isClearable?: boolean;
disableAnimation?: boolean;
className?: string;
classNames?: SlotsToClasses<InputSlots>;
}
interface TextAreaProps {
label?: React.ReactNode;
value?: string;
defaultValue?: string;
placeholder?: string;
minRows?: number;
maxRows?: number;
disableAutosize?: boolean;
isRequired?: boolean;
isDisabled?: boolean;
isInvalid?: boolean;
size?: "sm" | "md" | "lg";
variant?: "flat" | "bordered" | "underlined" | "faded";
color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
className?: string;
classNames?: SlotsToClasses<InputSlots>;
}
interface InputOTPProps {
length?: number;
value?: string;
defaultValue?: string;
placeholder?: string;
isRequired?: boolean;
isDisabled?: boolean;
isInvalid?: boolean;
size?: "sm" | "md" | "lg";
variant?: "flat" | "bordered" | "underlined" | "faded";
color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
allowedKeys?: RegExp;
className?: string;
classNames?: SlotsToClasses<InputOTPSlots>;
onValueChange?: (value: string) => void;
onComplete?: (value: string) => void;
}
interface SelectProps<T> {
children?: React.ReactNode;
items?: Iterable<T>;
label?: React.ReactNode;
placeholder?: string;
description?: React.ReactNode;
errorMessage?: React.ReactNode | ((v: ValidationResult) => React.ReactNode);
validate?: (value: SelectValue<T>) => ValidationError | true | null | undefined;
selectionMode?: "single" | "multiple";
selectedKeys?: "all" | Iterable<Key>;
defaultSelectedKeys?: "all" | Iterable<Key>;
disallowEmptySelection?: boolean;
shouldFlip?: boolean;
isRequired?: boolean;
isInvalid?: boolean;
isDisabled?: boolean;
isLoading?: boolean;
size?: "sm" | "md" | "lg";
radius?: "none" | "sm" | "md" | "lg" | "full";
variant?: "flat" | "bordered" | "underlined" | "faded";
color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
className?: string;
classNames?: SlotsToClasses<SelectSlots>;
}Components for presenting data, images, and content in organized formats.
interface TableProps<T> {
children?: React.ReactNode;
"aria-label"?: string;
"aria-labelledby"?: string;
"aria-describedby"?: string;
layout?: "auto" | "fixed";
hideHeader?: boolean;
showSelectionCheckboxes?: boolean;
color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
selectionMode?: "none" | "single" | "multiple";
selectionBehavior?: "toggle" | "replace";
selectedKeys?: "all" | Iterable<Key>;
defaultSelectedKeys?: "all" | Iterable<Key>;
disallowEmptySelection?: boolean;
sortDescriptor?: SortDescriptor;
onSelectionChange?: (keys: Selection) => void;
onSortChange?: (descriptor: SortDescriptor) => void;
isHeaderSticky?: boolean;
isCompact?: boolean;
removeWrapper?: boolean;
isStriped?: boolean;
fullWidth?: boolean;
className?: string;
classNames?: SlotsToClasses<TableSlots>;
}
interface AvatarProps {
src?: string;
alt?: string;
name?: string;
icon?: React.ReactNode;
fallback?: React.ReactNode;
size?: "sm" | "md" | "lg";
radius?: "none" | "sm" | "md" | "lg" | "full";
color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
isBordered?: boolean;
isDisabled?: boolean;
isFocusable?: boolean;
showFallback?: boolean;
imgRef?: React.RefObject<HTMLImageElement>;
className?: string;
classNames?: SlotsToClasses<AvatarSlots>;
}Components for providing user feedback including loading states, notifications, and informational overlays.
interface ProgressProps {
label?: React.ReactNode;
size?: "sm" | "md" | "lg";
radius?: "none" | "sm" | "md" | "lg" | "full";
color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
value?: number;
minValue?: number;
maxValue?: number;
isIndeterminate?: boolean;
showValueLabel?: boolean;
valueLabel?: React.ReactNode;
formatOptions?: Intl.NumberFormatOptions;
isDisabled?: boolean;
disableAnimation?: boolean;
className?: string;
classNames?: SlotsToClasses<ProgressSlots>;
}
interface SpinnerProps {
label?: React.ReactNode;
size?: "sm" | "md" | "lg";
color?: "current" | "white" | "default" | "primary" | "secondary" | "success" | "warning" | "danger";
labelColor?: "foreground" | "primary" | "secondary" | "success" | "warning" | "danger";
className?: string;
classNames?: SlotsToClasses<SpinnerSlots>;
}
interface TooltipProps {
children: React.ReactElement;
content?: React.ReactNode;
isOpen?: boolean;
defaultOpen?: boolean;
placement?: Placement;
delay?: number;
closeDelay?: number;
isDisabled?: boolean;
shouldFlip?: boolean;
containerPadding?: number;
offset?: number;
crossOffset?: number;
showArrow?: boolean;
radius?: "none" | "sm" | "md" | "lg" | "full";
size?: "sm" | "md" | "lg";
color?: "default" | "foreground" | "primary" | "secondary" | "success" | "warning" | "danger";
className?: string;
classNames?: SlotsToClasses<TooltipSlots>;
}Modal dialogs, popovers, dropdowns and other overlay components for complex interactions.
interface ModalProps {
children: React.ReactNode;
size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "full";
radius?: "none" | "sm" | "md" | "lg";
shadow?: "sm" | "md" | "lg";
backdrop?: "transparent" | "opaque" | "blur";
scrollBehavior?: "inside" | "outside";
placement?: "auto" | "top" | "center" | "bottom";
isOpen?: boolean;
defaultOpen?: boolean;
isDismissable?: boolean;
isKeyboardDismissDisabled?: boolean;
hideCloseButton?: boolean;
shouldBlockScroll?: boolean;
portalContainer?: Element;
disableAnimation?: boolean;
motionProps?: MotionProps;
className?: string;
classNames?: SlotsToClasses<ModalSlots>;
onOpenChange?: (isOpen: boolean) => void;
onClose?: () => void;
}
interface PopoverProps {
children: React.ReactNode;
size?: "sm" | "md" | "lg";
color?: "default" | "foreground" | "primary" | "secondary" | "success" | "warning" | "danger";
radius?: "none" | "sm" | "md" | "lg" | "full";
shadow?: "sm" | "md" | "lg";
backdrop?: "transparent" | "opaque" | "blur";
placement?: Placement;
isOpen?: boolean;
defaultOpen?: boolean;
shouldFlip?: boolean;
shouldUpdatePosition?: boolean;
shouldBlockScroll?: boolean;
isDismissable?: boolean;
shouldCloseOnBlur?: boolean;
shouldCloseOnInteractOutside?: (element: Element) => boolean;
isKeyboardDismissDisabled?: boolean;
showArrow?: boolean;
offset?: number;
crossOffset?: number;
containerPadding?: number;
triggerRef?: React.RefObject<Element>;
scrollRef?: React.RefObject<Element>;
portalContainer?: Element;
disableAnimation?: boolean;
motionProps?: MotionProps;
className?: string;
classNames?: SlotsToClasses<PopoverSlots>;
onOpenChange?: (isOpen: boolean) => void;
}Components for date selection, calendar navigation, and time input with internationalization support.
interface CalendarProps<T extends DateValue> {
value?: T | null;
defaultValue?: T | null;
minValue?: DateValue | null;
maxValue?: DateValue | null;
isDateUnavailable?: (date: DateValue) => boolean;
autoFocus?: boolean;
focusedValue?: DateValue | null;
defaultFocusedValue?: DateValue | null;
calendarWidth?: number;
visibleMonths?: number;
pageBehavior?: PageBehavior;
weekdayStyle?: "narrow" | "short" | "long";
showMonthAndYearPickers?: boolean;
isDisabled?: boolean;
isReadOnly?: boolean;
isInvalid?: boolean;
color?: "foreground" | "primary" | "secondary" | "success" | "warning" | "danger";
showHelper?: boolean;
topContent?: React.ReactNode;
bottomContent?: React.ReactNode;
errorMessage?: React.ReactNode | ((v: ValidationResult) => React.ReactNode);
validate?: (value: MappedDateValue<T>) => ValidationError | true | null | undefined;
validationBehavior?: "aria" | "native";
className?: string;
classNames?: SlotsToClasses<CalendarSlots>;
onFocusChange?: (date: CalendarDate) => void;
onChange?: (value: MappedDateValue<T>) => void;
}
interface DatePickerProps<T extends DateValue> extends Omit<DateInputProps<T>, "size"> {
size?: "sm" | "md" | "lg";
selectorIcon?: React.ReactNode;
calendarWidth?: number;
visibleMonths?: number;
pageBehavior?: PageBehavior;
calendarProps?: Partial<CalendarProps<T>>;
showMonthAndYearPickers?: boolean;
shouldCloseOnSelect?: boolean;
className?: string;
classNames?: SlotsToClasses<DatePickerSlots>;
}Advanced form handling components and integration patterns for validation and data collection.
interface FormProps {
children?: React.ReactNode;
validationErrors?: ValidationErrors;
validationBehavior?: "aria" | "native";
className?: string;
onReset?: () => void;
onSubmit?: (e: React.FormEvent<HTMLFormElement>) => void;
onInvalidSubmit?: (errors: ValidationErrors) => void;
}
// Validation types
type ValidationError = string | string[];
interface ValidationResult {
isInvalid: boolean;
validationErrors: string[];
validationDetails: ValidationDetails;
}
interface ValidationErrors {
[name: string]: ValidationError;
}Utility functions, custom hooks, and helper types for extending NextUI functionality.
// Disclosure hook for modal/popover state
interface UseDisclosureProps {
isOpen?: boolean;
defaultOpen?: boolean;
onClose?: () => void;
onOpenChange?: (isOpen: boolean) => void;
id?: string;
}
interface UseDisclosureReturn {
isOpen: boolean;
onOpen: () => void;
onClose: () => void;
onOpenChange: (isOpen: boolean) => void;
onToggle: () => void;
isControlled: boolean;
getButtonProps: (props?: any) => any;
getDisclosureProps: (props?: any) => any;
}
function useDisclosure(props?: UseDisclosureProps): UseDisclosureReturn;
// Utility functions
function forwardRef<T, P = {}>(
render: (props: P, ref: React.Ref<T>) => React.ReactElement | null
): (props: P & React.RefAttributes<T>) => React.ReactElement | null;
function cn(...inputs: ClassValue[]): string;
// Resizable panel for flexible layouts
interface ResizablePanelProps {
children: React.ReactNode;
defaultSize?: number;
minSize?: number;
maxSize?: number;
direction?: "horizontal" | "vertical";
isDisabled?: boolean;
id?: string;
className?: string;
onSizeChange?: (size: number) => void;
}
function ResizablePanel(props: ResizablePanelProps): JSX.Element;// Size variants used across components
type Size = "sm" | "md" | "lg";
// Color variants for theming
type Color = "default" | "primary" | "secondary" | "success" | "warning" | "danger";
// Radius variants for rounded corners
type Radius = "none" | "sm" | "md" | "lg" | "full";
// Common component slots
type SlotsToClasses<S extends string> = {
[key in S]?: string;
};
// Selection types
type Selection = "all" | Set<React.Key>;
type SelectionMode = "none" | "single" | "multiple";
type SelectionBehavior = "toggle" | "replace";
// Validation types
type ValidationBehavior = "aria" | "native";
interface ValidationResult {
isInvalid: boolean;
validationErrors: string[];
validationDetails: ValidationDetails;
}
// Date types (re-exported from @internationalized/date)
type DateValue = CalendarDate | CalendarDateTime | ZonedDateTime;
type MappedDateValue<T> = T extends ZonedDateTime ? ZonedDateTime :
T extends CalendarDateTime ? CalendarDateTime :
CalendarDate;
// Placement for overlays
type Placement =
| "top" | "top-start" | "top-end"
| "bottom" | "bottom-start" | "bottom-end"
| "right" | "right-start" | "right-end"
| "left" | "left-start" | "left-end";
// Animation and motion types
interface MotionProps {
initial?: any;
animate?: any;
exit?: any;
transition?: any;
variants?: any;
}
// Button-specific types
type ButtonSlots = "base";
type ButtonGroupSlots = "base";
// Press event from React Aria
interface PressEvent {
/** The type of press event being fired */
type: 'pressstart' | 'pressend' | 'pressup' | 'press';
/** The pointer type that triggered the press event */
pointerType: 'mouse' | 'pen' | 'touch' | 'keyboard' | 'virtual';
/** The target element of the press event */
target: Element;
/** Whether the shift keyboard modifier was held during the press event */
shiftKey: boolean;
/** Whether the ctrl keyboard modifier was held during the press event */
ctrlKey: boolean;
/** Whether the meta keyboard modifier was held during the press event */
metaKey: boolean;
/** Whether the alt keyboard modifier was held during the press event */
altKey: boolean;
}