CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-nextui-org--react

Beautiful and modern React UI library with comprehensive components, theming, and accessibility support.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

feedback.mddocs/

Feedback Components

NextUI provides comprehensive feedback components for communicating system status, user notifications, loading states, and contextual information to enhance user experience.

Capabilities

Alert

Notification component for displaying important messages, warnings, and status information with customizable styling and actions.

interface AlertProps {
  /** Alert content */
  children?: React.ReactNode;
  /** Alert title */
  title?: React.ReactNode;
  /** Alert description */
  description?: React.ReactNode;
  /** Alert color theme */
  color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
  /** Alert variant */
  variant?: "solid" | "bordered" | "light" | "flat" | "faded";
  /** Border radius */
  radius?: "none" | "sm" | "md" | "lg" | "full";
  /** Start content (icon, etc.) */
  startContent?: React.ReactNode;
  /** End content (action buttons, etc.) */
  endContent?: React.ReactNode;
  /** Whether alert is closeable */
  isClosable?: boolean;
  /** Whether alert is visible */
  isVisible?: boolean;
  /** Default visibility state */
  defaultVisible?: boolean;
  /** Hide icon */
  hideIconWrapper?: boolean;
  /** Custom CSS class */
  className?: string;
  /** Slot-based styling */
  classNames?: SlotsToClasses<AlertSlots>;
  /** Close event handler */
  onClose?: () => void;
  /** Visibility change handler */
  onVisibilityChange?: (isVisible: boolean) => void;
}

type AlertSlots = 
  | "base" | "wrapper" | "iconWrapper" | "icon"
  | "mainWrapper" | "title" | "description" 
  | "closeButton" | "closeIcon";

function Alert(props: AlertProps): JSX.Element;

/**
 * Hook for Alert state management
 */
function useAlert(props: AlertProps): {
  Component: React.ElementType;
  slots: Record<AlertSlots, string>;
  classNames: SlotsToClasses<AlertSlots>;
  isVisible: boolean;
  getAlertProps: () => any;
  getWrapperProps: () => any;
  getIconWrapperProps: () => any;
  getMainWrapperProps: () => any;
  getTitleProps: () => any;
  getDescriptionProps: () => any;
  getCloseButtonProps: () => any;
};

Alert Usage Examples:

import { Alert, Button } from "@nextui-org/react";
import { InfoIcon, CheckIcon, WarningIcon } from "@heroicons/react/24/solid";

function AlertExamples() {
  const [isVisible, setIsVisible] = useState(true);

  return (
    <div className="space-y-4">
      {/* Basic alerts */}
      <Alert color="primary" title="Info Alert">
        This is an informational message.
      </Alert>

      <Alert 
        color="success" 
        variant="bordered"
        startContent={<CheckIcon className="w-5 h-5" />}
        title="Success!"
        description="Your action was completed successfully."
      />

      <Alert
        color="warning"
        variant="flat"
        startContent={<WarningIcon className="w-5 h-5" />}
        title="Warning"
        description="Please review the following items before continuing."
      />

      <Alert
        color="danger"
        variant="light"
        title="Error"
        description="Something went wrong. Please try again."
        endContent={
          <Button color="danger" size="sm" variant="flat">
            Retry
          </Button>
        }
      />

      {/* Closeable alert */}
      <Alert
        color="secondary"
        title="Dismissible Alert"
        description="This alert can be closed by clicking the X button."
        isClosable
        isVisible={isVisible}
        onVisibilityChange={setIsVisible}
      />
    </div>
  );
}

Progress

Linear progress bar component for displaying completion status with customizable appearance and value formatting.

interface ProgressProps {
  /** Progress label */
  label?: React.ReactNode;
  /** Progress size */
  size?: "sm" | "md" | "lg";
  /** Border radius */
  radius?: "none" | "sm" | "md" | "lg" | "full";
  /** Color theme */
  color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
  /** Current progress value (0-100) */
  value?: number;
  /** Minimum value */
  minValue?: number;
  /** Maximum value */
  maxValue?: number;
  /** Indeterminate loading state */
  isIndeterminate?: boolean;
  /** Show value label */
  showValueLabel?: boolean;
  /** Custom value label */
  valueLabel?: React.ReactNode;
  /** Number formatting options */
  formatOptions?: Intl.NumberFormatOptions;
  /** Disabled state */
  isDisabled?: boolean;
  /** Disable animations */
  disableAnimation?: boolean;
  /** Custom CSS class */
  className?: string;
  /** Slot-based styling */
  classNames?: SlotsToClasses<ProgressSlots>;
  /** Value change handler */
  onValueChange?: (value: number) => void;
}

type ProgressSlots = "base" | "labelWrapper" | "label" | "value" | "track" | "indicator";

function Progress(props: ProgressProps): JSX.Element;

/**
 * Hook for Progress state management
 */
function useProgress(props: ProgressProps): {
  Component: React.ElementType;
  slots: Record<ProgressSlots, string>;
  classNames: SlotsToClasses<ProgressSlots>;
  progressBarProps: any;
  labelProps: any;
  percentage: number;
  getProgressBarProps: () => any;
  getLabelProps: () => any;
};

Circular Progress

Circular progress indicator for compact loading states and completion visualization.

interface CircularProgressProps {
  /** Progress label */
  label?: React.ReactNode;
  /** Progress size */
  size?: "sm" | "md" | "lg";
  /** Color theme */
  color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
  /** Current progress value (0-100) */
  value?: number;
  /** Minimum value */
  minValue?: number;
  /** Maximum value */
  maxValue?: number;
  /** Indeterminate loading state */
  isIndeterminate?: boolean;
  /** Show value label */
  showValueLabel?: boolean;
  /** Custom value label */
  valueLabel?: React.ReactNode;
  /** Number formatting options */
  formatOptions?: Intl.NumberFormatOptions;
  /** Disabled state */
  isDisabled?: boolean;
  /** Disable animations */
  disableAnimation?: boolean;
  /** Stroke width */
  strokeWidth?: number;
  /** Custom CSS class */
  className?: string;
  /** Slot-based styling */
  classNames?: SlotsToClasses<CircularProgressSlots>;
  /** Value change handler */
  onValueChange?: (value: number) => void;
}

type CircularProgressSlots = 
  | "base" | "svgWrapper" | "svg" | "track" | "indicator" 
  | "value" | "label";

function CircularProgress(props: CircularProgressProps): JSX.Element;

Progress Usage Examples:

import { Progress, CircularProgress, Button } from "@nextui-org/react";

function ProgressExamples() {
  const [value, setValue] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setValue((v) => (v >= 100 ? 0 : v + 10));
    }, 500);

    return () => clearInterval(interval);
  }, []);

  return (
    <div className="space-y-6">
      {/* Linear progress */}
      <div className="space-y-3">
        <Progress
          aria-label="Loading..."
          size="md"
          value={value}
          color="success"
          showValueLabel={true}
          className="max-w-md"
        />

        <Progress
          label="Loading files..."
          size="sm"
          isIndeterminate
          color="primary"
          className="max-w-md"
        />

        <Progress
          size="lg"
          radius="sm"
          classNames={{
            base: "max-w-md",
            track: "drop-shadow-md border border-default",
            indicator: "bg-gradient-to-r from-pink-500 to-yellow-500",
            label: "tracking-wider font-medium text-default-600",
            value: "text-foreground/60",
          }}
          label="Custom styled progress"
          value={65}
          showValueLabel={true}
        />
      </div>

      {/* Circular progress */}
      <div className="flex gap-6 items-center">
        <CircularProgress
          aria-label="Loading..."
          size="lg"
          value={value}
          color="warning"
          showValueLabel={true}
        />

        <CircularProgress
          label="CPU Usage"
          size="lg"
          value={70}
          color="danger"
          formatOptions={{ style: "unit", unit: "percent" }}
          showValueLabel={true}
        />

        <CircularProgress
          size="sm"
          isIndeterminate
          color="secondary"
          aria-label="Loading..."
        />
      </div>
    </div>
  );
}

Spinner

Loading spinner component for indicating processing states with various sizes and colors.

interface SpinnerProps {
  /** Spinner label */
  label?: React.ReactNode;
  /** Spinner size */
  size?: "sm" | "md" | "lg";
  /** Spinner color */
  color?: "current" | "white" | "default" | "primary" | "secondary" | "success" | "warning" | "danger";
  /** Label color */
  labelColor?: "foreground" | "primary" | "secondary" | "success" | "warning" | "danger";
  /** Custom CSS class */
  className?: string;
  /** Slot-based styling */
  classNames?: SlotsToClasses<SpinnerSlots>;
}

type SpinnerSlots = "base" | "wrapper" | "circle1" | "circle2" | "label";

function Spinner(props: SpinnerProps): JSX.Element;

/**
 * Hook for Spinner state management
 */
function useSpinner(props: SpinnerProps): {
  Component: React.ElementType;
  slots: Record<SpinnerSlots, string>;
  classNames: SlotsToClasses<SpinnerSlots>;
  getSpinnerProps: () => any;
  getWrapperProps: () => any;
  getLabelProps: () => any;
};

Spinner Usage Examples:

import { Spinner, Card, CardBody } from "@nextui-org/react";

function SpinnerExamples() {
  return (
    <div className="space-y-6">
      {/* Basic spinners */}
      <div className="flex gap-4 items-center">
        <Spinner size="sm" />
        <Spinner size="md" />
        <Spinner size="lg" />
      </div>

      {/* Colored spinners */}
      <div className="flex gap-4 items-center">
        <Spinner color="primary" />
        <Spinner color="secondary" />
        <Spinner color="success" />
        <Spinner color="warning" />
        <Spinner color="danger" />
      </div>

      {/* Spinner with labels */}
      <div className="flex flex-col gap-4">
        <Spinner label="Loading..." />
        
        <Spinner 
          label="Processing your request" 
          color="warning"
          labelColor="warning"
        />
      </div>

      {/* Spinner in content */}
      <Card>
        <CardBody className="flex items-center justify-center py-8">
          <Spinner 
            size="lg" 
            label="Loading content..." 
            color="primary"
          />
        </CardBody>
      </Card>
    </div>
  );
}

Skeleton

Placeholder loading component that mimics content structure during data loading.

interface SkeletonProps {
  /** Skeleton content */
  children?: React.ReactNode;
  /** Whether skeleton is loading */
  isLoaded?: boolean;
  /** Disable animations */
  disableAnimation?: boolean;
  /** Custom CSS class */
  className?: string;
}

function Skeleton(props: SkeletonProps): JSX.Element;

/**
 * Hook for Skeleton state management
 */
function useSkeleton(props: SkeletonProps): {
  Component: React.ElementType;
  getSkeletonProps: () => any;
};

Skeleton Usage Examples:

import { Skeleton, Card, CardHeader, CardBody, Avatar } from "@nextui-org/react";

function SkeletonExamples() {
  const [isLoaded, setIsLoaded] = useState(false);

  useEffect(() => {
    const timer = setTimeout(() => setIsLoaded(true), 3000);
    return () => clearTimeout(timer);
  }, []);

  return (
    <div className="space-y-6">
      {/* Content skeleton */}
      <Card className="w-[200px] space-y-5 p-4" radius="lg">
        <Skeleton isLoaded={isLoaded} className="rounded-lg">
          <div className="h-24 rounded-lg bg-secondary"></div>
        </Skeleton>
        <div className="space-y-3">
          <Skeleton isLoaded={isLoaded} className="w-3/5 rounded-lg">
            <div className="h-3 w-full rounded-lg bg-secondary"></div>
          </Skeleton>
          <Skeleton isLoaded={isLoaded} className="w-4/5 rounded-lg">
            <div className="h-3 w-full rounded-lg bg-secondary-300"></div>
          </Skeleton>
          <Skeleton isLoaded={isLoaded} className="w-2/5 rounded-lg">
            <div className="h-3 w-full rounded-lg bg-secondary-200"></div>
          </Skeleton>
        </div>
      </Card>

      {/* User profile skeleton */}
      <Card className="max-w-[300px]">
        <CardHeader className="justify-between">
          <div className="flex gap-5">
            <Skeleton isLoaded={isLoaded} className="flex rounded-full w-12 h-12">
              <Avatar
                isBordered
                radius="full"
                size="md"
                src="https://nextui.org/avatars/avatar-1.png"
              />
            </Skeleton>
            <div className="flex flex-col gap-1 items-start justify-center">
              <Skeleton isLoaded={isLoaded} className="w-20 rounded-lg">
                <h4 className="text-small font-semibold leading-none text-default-600">
                  Zoey Lang
                </h4>
              </Skeleton>
              <Skeleton isLoaded={isLoaded} className="w-16 rounded-lg">
                <h5 className="text-small tracking-tight text-default-400">
                  @zoeylang
                </h5>
              </Skeleton>
            </div>
          </div>
          <Skeleton isLoaded={isLoaded} className="rounded-lg">
            <Button color="primary" radius="full" size="sm">
              Follow
            </Button>
          </Skeleton>
        </CardHeader>
        <CardBody className="px-3 py-0 text-small text-default-400">
          <Skeleton isLoaded={isLoaded} className="rounded-lg">
            <p>
              Frontend developer and UI/UX enthusiast. Join me on this coding adventure!
            </p>
          </Skeleton>
        </CardBody>
      </Card>
    </div>
  );
}

Tooltip

Contextual information overlay that appears on hover or focus to provide additional details.

interface TooltipProps {
  /** Target element to attach tooltip to */
  children: React.ReactElement;
  /** Tooltip content */
  content?: React.ReactNode;
  /** Whether tooltip is open */
  isOpen?: boolean;
  /** Default open state */
  defaultOpen?: boolean;
  /** Tooltip placement */
  placement?: Placement;
  /** Show delay in milliseconds */
  delay?: number;
  /** Close delay in milliseconds */
  closeDelay?: number;
  /** Disabled state */
  isDisabled?: boolean;
  /** Whether tooltip should flip to fit */
  shouldFlip?: boolean;
  /** Container padding for flip calculations */
  containerPadding?: number;
  /** Offset from target */
  offset?: number;
  /** Cross-axis offset */
  crossOffset?: number;
  /** Show arrow pointer */
  showArrow?: boolean;
  /** Border radius */
  radius?: "none" | "sm" | "md" | "lg" | "full";
  /** Tooltip size */
  size?: "sm" | "md" | "lg";
  /** Color theme */
  color?: "default" | "foreground" | "primary" | "secondary" | "success" | "warning" | "danger";
  /** Motion configuration */
  motionProps?: MotionProps;
  /** Custom CSS class */
  className?: string;
  /** Slot-based styling */
  classNames?: SlotsToClasses<TooltipSlots>;
  /** Open change handler */
  onOpenChange?: (isOpen: boolean) => void;
}

type TooltipSlots = "base" | "arrow" | "content";

type Placement = 
  | "top" | "top-start" | "top-end"
  | "bottom" | "bottom-start" | "bottom-end"
  | "right" | "right-start" | "right-end"
  | "left" | "left-start" | "left-end";

function Tooltip(props: TooltipProps): JSX.Element;

/**
 * Hook for Tooltip state management
 */
function useTooltip(props: TooltipProps): {
  Component: React.ElementType;
  isOpen: boolean;
  disableAnimation: boolean;
  getTooltipProps: () => any;
  getTriggerProps: () => any;
  getTooltipContentProps: () => any;
};

Tooltip Usage Examples:

import { Tooltip, Button } from "@nextui-org/react";
import { DeleteIcon, EditIcon, EyeIcon } from "@heroicons/react/24/solid";

function TooltipExamples() {
  return (
    <div className="space-y-6">
      {/* Basic tooltips */}
      <div className="flex gap-4 items-center">
        <Tooltip content="I am a tooltip">
          <Button>Hover me</Button>
        </Tooltip>

        <Tooltip content="Tooltip with arrow" showArrow>
          <Button color="primary">With Arrow</Button>
        </Tooltip>
      </div>

      {/* Colored tooltips */}
      <div className="flex gap-4 items-center">
        <Tooltip content="Edit" color="success" showArrow>
          <Button isIconOnly color="success" variant="light">
            <EditIcon className="w-4 h-4" />
          </Button>
        </Tooltip>

        <Tooltip content="View" color="secondary" showArrow>
          <Button isIconOnly color="secondary" variant="light">
            <EyeIcon className="w-4 h-4" />
          </Button>
        </Tooltip>

        <Tooltip content="Delete" color="danger" showArrow>
          <Button isIconOnly color="danger" variant="light">
            <DeleteIcon className="w-4 h-4" />
          </Button>
        </Tooltip>
      </div>

      {/* Placement variations */}
      <div className="flex flex-wrap gap-4">
        {["top", "bottom", "left", "right"].map((placement) => (
          <Tooltip 
            key={placement}
            content={`Tooltip on ${placement}`}
            placement={placement as Placement}
            showArrow
          >
            <Button variant="bordered" className="capitalize">
              {placement}
            </Button>
          </Tooltip>
        ))}
      </div>

      {/* Custom content tooltip */}
      <Tooltip
        showArrow
        content={
          <div className="px-1 py-2">
            <div className="text-small font-bold">Custom Content</div>
            <div className="text-tiny">This tooltip has custom styling</div>
          </div>
        }
      >
        <Button color="secondary" variant="flat">
          Custom Content
        </Button>
      </Tooltip>
    </div>
  );
}

Feedback Component Types

// Common feedback types
type FeedbackSize = "sm" | "md" | "lg";
type FeedbackColor = "default" | "primary" | "secondary" | "success" | "warning" | "danger";
type FeedbackRadius = "none" | "sm" | "md" | "lg" | "full";

// Alert types
interface AlertState {
  isVisible: boolean;
  isClosable: boolean;
  color: FeedbackColor;
  variant: "solid" | "bordered" | "light" | "flat" | "faded";
}

// Progress types
interface ProgressState {
  value: number;
  minValue: number;
  maxValue: number;
  percentage: number;
  isIndeterminate: boolean;
  valueLabel: string;
}

// Tooltip types
interface TooltipState {
  isOpen: boolean;
  placement: Placement;
  isDisabled: boolean;
  showArrow: boolean;
  delay: number;
  closeDelay: number;
}

// Motion configuration for animations
interface MotionProps {
  initial?: any;
  animate?: any;
  exit?: any;
  transition?: any;
  variants?: any;
  whileHover?: any;
  whileTap?: any;
  whileFocus?: any;
  whileInView?: any;
}

// Placement type for positioning
type PlacementAxis = "top" | "bottom" | "left" | "right";
type PlacementAlign = "start" | "end";
type Placement = PlacementAxis | `${PlacementAxis}-${PlacementAlign}`;

// Number formatting for progress values
interface ProgressFormatOptions extends Intl.NumberFormatOptions {
  style?: "decimal" | "currency" | "percent" | "unit";
  unit?: string;
  currency?: string;
  minimumFractionDigits?: number;
  maximumFractionDigits?: number;
}

Integration Examples

Loading States Pattern

import { 
  Skeleton, Spinner, Progress, Alert, Button, Card, CardBody 
} from "@nextui-org/react";

function LoadingStatesExample() {
  const [loadingState, setLoadingState] = useState<'idle' | 'loading' | 'error' | 'success'>('idle');
  const [progress, setProgress] = useState(0);

  const handleAction = async () => {
    setLoadingState('loading');
    setProgress(0);

    try {
      // Simulate progress updates
      for (let i = 0; i <= 100; i += 10) {
        setProgress(i);
        await new Promise(resolve => setTimeout(resolve, 200));
      }
      
      setLoadingState('success');
    } catch (error) {
      setLoadingState('error');
    }
  };

  return (
    <div className="space-y-6 max-w-md">
      {loadingState === 'loading' && (
        <Card>
          <CardBody className="space-y-4">
            <div className="flex items-center gap-4">
              <Spinner size="sm" color="primary" />
              <span>Processing...</span>
            </div>
            <Progress 
              value={progress} 
              color="primary"
              showValueLabel
            />
          </CardBody>
        </Card>
      )}

      {loadingState === 'success' && (
        <Alert
          color="success"
          title="Success!"
          description="Your action was completed successfully."
        />
      )}

      {loadingState === 'error' && (
        <Alert
          color="danger"
          title="Error"
          description="Something went wrong. Please try again."
          endContent={
            <Button 
              color="danger" 
              variant="flat" 
              size="sm"
              onPress={() => setLoadingState('idle')}
            >
              Retry
            </Button>
          }
        />
      )}

      <Button 
        color="primary"
        onPress={handleAction}
        isDisabled={loadingState === 'loading'}
      >
        {loadingState === 'loading' ? 'Processing...' : 'Start Action'}
      </Button>
    </div>
  );
}

Notification System

import { Alert, Button } from "@nextui-org/react";

function NotificationSystem() {
  const [notifications, setNotifications] = useState<Array<{
    id: string;
    type: 'success' | 'warning' | 'danger' | 'info';
    title: string;
    message: string;
  }>>([]);

  const addNotification = (type: string, title: string, message: string) => {
    const notification = {
      id: Date.now().toString(),
      type,
      title,
      message,
    };
    setNotifications(prev => [...prev, notification]);
    
    // Auto remove after 5 seconds
    setTimeout(() => {
      removeNotification(notification.id);
    }, 5000);
  };

  const removeNotification = (id: string) => {
    setNotifications(prev => prev.filter(n => n.id !== id));
  };

  return (
    <div className="space-y-4">
      {/* Notification triggers */}
      <div className="flex gap-2">
        <Button 
          color="success" 
          onPress={() => addNotification('success', 'Success', 'Operation completed successfully!')}
        >
          Success
        </Button>
        <Button 
          color="warning" 
          onPress={() => addNotification('warning', 'Warning', 'Please review your input.')}
        >
          Warning
        </Button>
        <Button 
          color="danger" 
          onPress={() => addNotification('danger', 'Error', 'Something went wrong.')}
        >
          Error
        </Button>
      </div>

      {/* Notifications display */}
      <div className="fixed top-4 right-4 space-y-2 z-50">
        {notifications.map((notification) => (
          <Alert
            key={notification.id}
            color={notification.type}
            title={notification.title}
            description={notification.message}
            isClosable
            onClose={() => removeNotification(notification.id)}
            className="max-w-sm"
          />
        ))}
      </div>
    </div>
  );
}

docs

core-system.md

data-display.md

date-time.md

feedback.md

forms.md

index.md

inputs.md

interactions.md

layout.md

navigation.md

overlays.md

utilities.md

tile.json