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

utilities.mddocs/

Utilities and Hooks

NextUI provides a comprehensive set of utility functions, custom hooks, and helper types that extend functionality and enable advanced customization patterns for building sophisticated user interfaces.

Capabilities

Disclosure Hook

A versatile hook for managing open/closed state in overlay components, modals, popovers, and other interactive elements.

interface UseDisclosureProps {
  /** Whether overlay is open */
  isOpen?: boolean;
  /** Default open state for uncontrolled mode */
  defaultOpen?: boolean;
  /** Close event handler */
  onClose?: () => void;
  /** Open change event handler */
  onOpenChange?: (isOpen: boolean) => void;
  /** Unique identifier for the disclosure */
  id?: string;
}

interface UseDisclosureReturn {
  /** Current open state */
  isOpen: boolean;
  /** Function to open the overlay */
  onOpen: () => void;
  /** Function to close the overlay */
  onClose: () => void;
  /** Function to toggle overlay state */
  onOpenChange: (isOpen: boolean) => void;
  /** Function to toggle between open and closed */
  onToggle: () => void;
  /** Whether the state is controlled externally */
  isControlled: boolean;
  /** Props for trigger button */
  getButtonProps: (props?: any) => any;
  /** Props for disclosure content */
  getDisclosureProps: (props?: any) => any;
}

/**
 * Hook for managing disclosure state (open/closed) for overlays
 * @param props Configuration options
 * @returns Disclosure state and handlers
 */
function useDisclosure(props?: UseDisclosureProps): UseDisclosureReturn;

Usage Examples:

import { useDisclosure, Modal, ModalContent, Button } from "@nextui-org/react";

function DisclosureExample() {
  // Basic usage
  const { isOpen, onOpen, onOpenChange } = useDisclosure();

  // Controlled usage
  const [modalOpen, setModalOpen] = useState(false);
  const modal = useDisclosure({
    isOpen: modalOpen,
    onOpenChange: setModalOpen,
  });

  // With default state
  const drawer = useDisclosure({ defaultOpen: true });

  return (
    <div className="space-y-4">
      {/* Basic modal */}
      <Button onPress={onOpen}>Open Modal</Button>
      <Modal isOpen={isOpen} onOpenChange={onOpenChange}>
        <ModalContent>
          <p>Modal content</p>
        </ModalContent>
      </Modal>

      {/* Controlled modal */}
      <Button onPress={modal.onOpen}>Controlled Modal</Button>
      <Modal isOpen={modal.isOpen} onOpenChange={modal.onOpenChange}>
        <ModalContent>
          <p>Controlled modal content</p>
        </ModalContent>
      </Modal>

      {/* Multiple disclosures */}
      <Button onPress={drawer.onToggle}>
        {drawer.isOpen ? "Close" : "Open"} Drawer
      </Button>
    </div>
  );
}

Draggable Hook

Advanced hook for implementing drag functionality with constraints and gestures.

interface UseDraggableProps {
  /** Whether dragging is disabled */
  isDisabled?: boolean;
  /** Target element reference */
  targetRef?: React.RefObject<HTMLElement>;
  /** Body element reference for constraints */
  bodyRef?: React.RefObject<HTMLElement>;
  /** Drag constraint boundaries */
  dragConstraints?: {
    top?: number;
    left?: number;
    right?: number;
    bottom?: number;
  } | React.RefObject<Element>;
  /** Elastic drag behavior */
  dragElastic?: boolean | number;
  /** Drag momentum configuration */
  dragMomentum?: boolean;
  /** Drag transition spring configuration */
  dragTransition?: {
    bounceStiffness?: number;
    bounceDamping?: number;
  };
}

interface UseDraggableReturn {
  /** Motion props for the draggable element */
  dragProps: {
    drag?: boolean | "x" | "y";
    dragConstraints?: any;
    dragElastic?: boolean | number;
    dragMomentum?: boolean;
    dragTransition?: any;
    dragControls?: any;
    onDragStart?: (event: any, info: any) => void;
    onDrag?: (event: any, info: any) => void;
    onDragEnd?: (event: any, info: any) => void;
  };
  /** Drag controls for programmatic control */
  dragControls: any;
}

/**
 * Hook for implementing draggable functionality with Framer Motion
 * @param props Drag configuration options
 * @returns Drag props and controls
 */
function useDraggable(props: UseDraggableProps): UseDraggableReturn;

Usage Example:

import { useDraggable, Card, CardBody } from "@nextui-org/react";
import { motion } from "framer-motion";

function DraggableExample() {
  const constraintsRef = useRef<HTMLDivElement>(null);
  const { dragProps } = useDraggable({
    dragConstraints: constraintsRef,
    dragElastic: 0.1,
  });

  return (
    <div 
      ref={constraintsRef}
      className="w-96 h-96 bg-default-100 rounded-lg relative"
    >
      <motion.div {...dragProps} className="absolute">
        <Card className="w-32 h-32 cursor-grab active:cursor-grabbing">
          <CardBody className="flex items-center justify-center">
            <p className="text-sm">Drag me!</p>
          </CardBody>
        </Card>
      </motion.div>
    </div>
  );
}

Ripple Hook

Hook for implementing Material Design ripple effects on interactive elements.

interface UseRippleProps {
  /** Ripple color theme */
  color?: "current" | "white" | "default" | "primary" | "secondary" | "success" | "warning" | "danger";
  /** Whether ripple is disabled */
  isDisabled?: boolean;
  /** Disable ripple for specific interactions */
  disableRipple?: boolean;
  /** Custom ripple duration in milliseconds */
  duration?: number;
}

interface UseRippleReturn {
  /** Ripple component to render */
  ripples: React.ReactNode;
  /** Function to trigger ripple effect */
  onClick: (event: React.MouseEvent) => void;
  /** Clear all active ripples */
  clear: () => void;
}

/**
 * Hook for Material Design ripple effects
 * @param props Ripple configuration
 * @returns Ripple state and handlers
 */
function useRipple(props?: UseRippleProps): UseRippleReturn;

Usage Example:

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

function RippleExample() {
  const { ripples, onClick } = useRipple({
    color: "primary",
  });

  return (
    <Card 
      isPressable
      className="w-64 h-32 relative overflow-hidden"
      onPress={onClick}
    >
      <CardBody className="flex items-center justify-center">
        <p>Click for ripple effect</p>
        {ripples}
      </CardBody>
    </Card>
  );
}

Scroll Shadow Hook

Hook for implementing scroll shadows that indicate scrollable content overflow.

interface UseScrollShadowProps {
  /** Scroll container reference */
  ref?: React.RefObject<HTMLElement>;
  /** Shadow visibility configuration */
  visibility?: "auto" | "top" | "bottom" | "left" | "right" | "both" | "none";
  /** Scroll orientation for shadow calculation */
  orientation?: "vertical" | "horizontal";
  /** Whether shadows are enabled */
  isEnabled?: boolean;
  /** Shadow size in pixels */
  size?: number;
  /** Offset threshold before showing shadows */
  offset?: number;
  /** Update interval for scroll position checking */
  updateInterval?: number;
}

interface UseScrollShadowReturn {
  /** Scroll container ref to attach */
  scrollRef: React.RefObject<HTMLElement>;
  /** Whether top shadow should be visible */
  isTopShadowVisible: boolean;
  /** Whether bottom shadow should be visible */
  isBottomShadowVisible: boolean;
  /** Whether left shadow should be visible */
  isLeftShadowVisible: boolean;
  /** Whether right shadow should be visible */
  isRightShadowVisible: boolean;
  /** Current scroll position */
  scrollPosition: { top: number; left: number };
  /** Scroll container dimensions */
  dimensions: {
    scrollWidth: number;
    scrollHeight: number;
    clientWidth: number;
    clientHeight: number;
  };
}

/**
 * Hook for scroll shadow functionality
 * @param props Scroll shadow configuration
 * @returns Scroll shadow state and refs
 */
function useScrollShadow(props?: UseScrollShadowProps): UseScrollShadowReturn;

Usage Example:

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

function ScrollShadowExample() {
  const {
    scrollRef,
    isTopShadowVisible,
    isBottomShadowVisible
  } = useScrollShadow({
    orientation: "vertical",
    size: 8,
  });

  const items = Array.from({ length: 50 }, (_, i) => `Item ${i + 1}`);

  return (
    <Card className="w-64 h-96 relative">
      <CardBody className="p-0">
        {/* Top shadow */}
        {isTopShadowVisible && (
          <div className="absolute top-0 left-0 right-0 h-8 bg-gradient-to-b from-background to-transparent z-10 pointer-events-none" />
        )}
        
        {/* Scrollable content */}
        <div 
          ref={scrollRef}
          className="h-full overflow-y-auto p-4 space-y-2"
        >
          {items.map((item) => (
            <div key={item} className="p-2 bg-default-100 rounded">
              {item}
            </div>
          ))}
        </div>
        
        {/* Bottom shadow */}
        {isBottomShadowVisible && (
          <div className="absolute bottom-0 left-0 right-0 h-8 bg-gradient-to-t from-background to-transparent z-10 pointer-events-none" />
        )}
      </CardBody>
    </Card>
  );
}

Provider Context Hook

Hook for accessing NextUI provider configuration throughout the component tree.

interface ProviderContextProps {
  /** Current theme */
  theme?: "light" | "dark";
  /** Available themes */
  themes?: ConfigThemes;
  /** Default theme key */
  defaultTheme?: string;
  /** Whether animations are disabled globally */
  disableAnimation?: boolean;
  /** Whether ripple effects are disabled globally */
  disableRipple?: boolean;
  /** Validation behavior mode */
  validationBehavior?: "aria" | "native";
  /** Current locale */
  locale?: string;
  /** Navigation function for client-side routing */
  navigate?: (path: string) => void;
  /** Whether portal container is created */
  createPortalContainer?: boolean;
}

/**
 * Hook to access NextUI provider context
 * @returns Provider context props or undefined if outside provider
 */
function useProviderContext(): ProviderContextProps | undefined;

Usage Example:

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

function ThemeAwareComponent() {
  const context = useProviderContext();
  
  const handleThemeToggle = () => {
    // Access theme configuration
    const currentTheme = context?.theme;
    console.log("Current theme:", currentTheme);
  };

  return (
    <Card>
      <CardBody>
        <p>Current theme: {context?.theme || "No theme"}</p>
        <p>Animations: {context?.disableAnimation ? "Disabled" : "Enabled"}</p>
        <p>Locale: {context?.locale || "Default"}</p>
        <Button 
          onPress={handleThemeToggle}
          color="primary"
        >
          Check Theme
        </Button>
      </CardBody>
    </Card>
  );
}

Forwarded Ref Utility

Enhanced forwardRef function that works seamlessly with NextUI's component system.

/**
 * Enhanced forwardRef function for NextUI components
 * @param render Render function that receives props and ref
 * @returns Forwarded ref component
 */
function forwardRef<T, P = {}>(
  render: (props: P, ref: React.Ref<T>) => React.ReactElement | null
): (props: P & React.RefAttributes<T>) => React.ReactElement | null;

Usage Example:

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

interface CustomButtonProps {
  variant?: "primary" | "secondary";
  children: React.ReactNode;
}

const CustomButton = forwardRef<HTMLButtonElement, CustomButtonProps>(
  ({ variant = "primary", children, ...props }, ref) => {
    return (
      <Button
        ref={ref}
        color={variant}
        {...props}
      >
        {children}
      </Button>
    );
  }
);

// Usage
function App() {
  const buttonRef = useRef<HTMLButtonElement>(null);
  
  return (
    <CustomButton 
      ref={buttonRef}
      variant="secondary"
      onPress={() => buttonRef.current?.focus()}
    >
      Custom Button
    </CustomButton>
  );
}

Class Name Utilities

Utility functions for working with CSS classes and styling.

/**
 * Class name utility (alias for clsx/cn)
 * @param inputs Class name inputs (strings, objects, arrays)
 * @returns Merged class name string
 */
function cn(...inputs: ClassValue[]): string;

type ClassValue = 
  | string
  | number
  | boolean
  | undefined
  | null
  | ClassValue[]
  | Record<string, any>;

/**
 * Merge classes utility for combining class strings
 * @param classes Class name strings to merge
 * @returns Combined class string
 */
function mergeClasses(...classes: string[]): string;

Usage Examples:

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

function ClassUtilityExample() {
  const [isActive, setIsActive] = useState(false);
  const [variant, setVariant] = useState<"primary" | "secondary">("primary");

  // Using cn for conditional classes
  const cardClasses = cn(
    "transition-all duration-200",
    {
      "scale-105 shadow-lg": isActive,
      "bg-primary": variant === "primary",
      "bg-secondary": variant === "secondary",
    }
  );

  // Using cn with arrays
  const buttonClasses = cn([
    "px-4 py-2 rounded",
    isActive && "bg-primary text-white",
    !isActive && "bg-gray-200 text-gray-700"
  ]);

  return (
    <div className="space-y-4">
      <Card 
        className={cardClasses}
        isPressable
        onPress={() => setIsActive(!isActive)}
      >
        <CardBody>
          <p>Click to toggle active state</p>
          <p>Current variant: {variant}</p>
        </CardBody>
      </Card>

      <button 
        className={buttonClasses}
        onClick={() => setIsActive(!isActive)}
      >
        Toggle Active
      </button>
    </div>
  );
}

Iterator Utilities

Utilities for working with iterables and collections.

/**
 * Convert value to iterator
 * @param value Iterable or function that returns iterable
 * @returns Iterator instance
 */
function toIterator<T>(value: Iterable<T> | (() => Iterable<T>)): Iterator<T>;

/**
 * Check if element is a NextUI component
 * @param element React element to check
 * @returns Whether element is NextUI component
 */
function isNextUIEl(element: React.ReactElement): boolean;

Usage Example:

import { toIterator, isNextUIEl, Button, Card } from "@nextui-org/react";

function IteratorExample() {
  // Convert array to iterator
  const items = ["apple", "banana", "cherry"];
  const iterator = toIterator(items);
  
  // Convert generator function to iterator
  function* numberGenerator() {
    for (let i = 0; i < 5; i++) {
      yield i;
    }
  }
  const numberIterator = toIterator(numberGenerator);

  // Check if elements are NextUI components
  const checkComponents = () => {
    const button = <Button>Test</Button>;
    const div = <div>Test</div>;
    const card = <Card>Test</Card>;
    
    console.log("Button is NextUI:", isNextUIEl(button)); // true
    console.log("Div is NextUI:", isNextUIEl(div)); // false
    console.log("Card is NextUI:", isNextUIEl(card)); // true
  };

  return (
    <div className="space-y-4">
      <Button onPress={checkComponents}>
        Check Components
      </Button>
      
      <div>
        <p>Iterator example:</p>
        <ul>
          {Array.from(iterator).map((item, index) => (
            <li key={index}>{item}</li>
          ))}
        </ul>
      </div>
    </div>
  );
}

Prop Mapping Utilities

Utilities for component variant and prop management.

/**
 * Map props to variants and common props
 * @param props Component props
 * @param variantKeys Keys that should be treated as variants
 * @param removeVariantProps Whether to remove variant props from main props
 * @returns Tuple of [remainingProps, variantProps]
 */
function mapPropsVariants<T, K extends keyof T>(
  props: T,
  variantKeys: K[],
  removeVariantProps?: boolean
): [Omit<T, K>, Pick<T, K>];

/**
 * Map props to variants and common props with additional common keys
 * @param props Component props
 * @param variantKeys Keys that should be treated as variants
 * @param commonKeys Keys that should be treated as common props
 * @param removeVariantProps Whether to remove variant props from main props
 * @returns Tuple of [remainingProps, variantProps, commonProps]
 */
function mapPropsVariantsWithCommon<T, K extends keyof T, C extends keyof T>(
  props: T,
  variantKeys: K[],
  commonKeys: C[],
  removeVariantProps?: boolean
): [Omit<T, K | C>, Pick<T, K>, Pick<T, C>];

Component Extension Utilities

Utilities for extending and customizing NextUI components.

/**
 * Extend component variants with custom styling
 * @param component Component function created with tv()
 * @param variants Additional variant configurations
 * @param defaultVariants Default variant selections
 * @returns Extended component function
 */
function extendVariants<T extends (...args: any[]) => any>(
  component: T,
  variants: ExtendVariantProps<T>,
  defaultVariants?: Record<string, any>
): T;

interface ExtendVariantProps<T> {
  /** Additional variants to add */
  variants?: Record<string, Record<string, any>>;
  /** Default variant values */
  defaultVariants?: Record<string, any>;
  /** Compound variants for complex styling */
  compoundVariants?: Array<{
    /** Variant conditions */
    [key: string]: any;
    /** Classes to apply when conditions match */
    class?: string | string[];
  }>;
}

Usage Example:

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

// Extend Button with custom variants
const CustomButton = extendVariants(Button, {
  variants: {
    color: {
      olive: "bg-[#84cc16] text-[#000] data-[hover=true]:bg-[#65a30d]",
      orange: "bg-[#ff8c00] text-[#fff] data-[hover=true]:bg-[#ff7700]",
      violet: "bg-[#8b5cf6] text-[#fff] data-[hover=true]:bg-[#7c3aed]",
    },
    isDisabled: {
      true: "bg-[#eaeaea] text-[#000] opacity-50 cursor-not-allowed",
    },
    size: {
      xs: "px-2 py-1 text-xs",
      xl: "px-8 py-4 text-xl",
    },
  },
  defaultVariants: {
    color: "olive",
    size: "md",
  },
  compoundVariants: [
    {
      color: "olive",
      size: "xl",
      class: "uppercase font-bold",
    },
  ],
});

function ExtendVariantsExample() {
  return (
    <div className="flex gap-4 items-center">
      <CustomButton color="olive" size="sm">
        Olive Button
      </CustomButton>
      <CustomButton color="orange" size="md">
        Orange Button
      </CustomButton>
      <CustomButton color="violet" size="xl">
        Violet XL Button
      </CustomButton>
    </div>
  );
}

Utility Types

// Common utility types
type Size = "sm" | "md" | "lg";
type Color = "default" | "primary" | "secondary" | "success" | "warning" | "danger";
type Radius = "none" | "sm" | "md" | "lg" | "full";
type Variant = "solid" | "bordered" | "light" | "flat" | "faded" | "shadow";

// Component polymorphism types
type As<Props = any> = React.ElementType<Props>;

type PropsOf<T extends As> = React.ComponentPropsWithoutRef<T> & {
  as?: T;
};

type OmitCommonProps<T, K extends keyof any = never> = Omit<T, "id" | "children" | K>;

type RightJoinProps<
  SourceProps extends object = {},
  OverrideProps extends object = {}
> = OmitCommonProps<SourceProps, keyof OverrideProps> & OverrideProps;

type MergeWithAs<
  ComponentProps extends object,
  AsProps extends object,
  AdditionalProps extends object = {},
  AsComponent extends As = As
> = RightJoinProps<ComponentProps, AdditionalProps> & 
    RightJoinProps<AsProps, AdditionalProps> & {
      as?: AsComponent;
    };

// Prop getter types
type PropGetter<P = Record<string, unknown>, R = Record<string, unknown>> = (
  props?: P,
  forwardedRef?: React.Ref<any>
) => R;

// Slot-based styling types
type SlotsToClasses<S extends string> = {
  [K in S]?: string;
};

type SlotProps<T> = T extends Record<infer S, any> ? S : never;

// Theme and variant types
interface ConfigThemes {
  light?: ConfigTheme;
  dark?: ConfigTheme;
  [key: string]: ConfigTheme | undefined;
}

interface ConfigTheme {
  colors?: Record<string, any>;
  layout?: LayoutTheme;
}

interface LayoutTheme {
  spacingUnit?: number;
  disableAnimation?: boolean;
  radius?: BaseThemeUnit;
  borderWidth?: BaseThemeUnit;
}

interface BaseThemeUnit {
  small?: string;
  medium?: string;
  large?: string;
}

// Selection types
type Selection = "all" | Set<React.Key>;
type SelectionMode = "none" | "single" | "multiple";
type SelectionBehavior = "toggle" | "replace";

interface SharedSelection {
  selectedKeys?: Selection;
  defaultSelectedKeys?: Selection;
  selectionMode?: SelectionMode;
  selectionBehavior?: SelectionBehavior;
  disallowEmptySelection?: boolean;
  onSelectionChange?: (keys: Selection) => void;
}

// Validation types
type ValidationBehavior = "aria" | "native";
type ValidationError = string | string[];

interface ValidationResult {
  isInvalid: boolean;
  validationErrors: string[];
  validationDetails: ValidationDetails;
}

interface ValidationDetails {
  [key: string]: any;
}

// Motion and animation types
interface MotionProps {
  initial?: any;
  animate?: any;
  exit?: any;
  transition?: any;
  variants?: any;
  whileHover?: any;
  whileTap?: any;
  whileFocus?: any;
  whileInView?: any;
}

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

// Date/Time utility types
type DateValue = CalendarDate | CalendarDateTime | ZonedDateTime;
type TimeValue = Time;

interface RangeValue<T> {
  start: T;
  end: T;
}

// Hook return type patterns
interface UseComponentReturn<TElement = HTMLElement> {
  Component: React.ElementType;
  domRef: React.RefObject<TElement>;
  slots: Record<string, string>;
  classNames: Record<string, string>;
  [key: string]: any;
}

// Event handler types
type PressHandler = () => void;
type ValueChangeHandler<T> = (value: T) => void;
type SelectionChangeHandler = (keys: Selection) => void;
type OpenChangeHandler = (isOpen: boolean) => void;

Integration Examples

Custom Hook Composition

Combining multiple NextUI hooks for complex functionality.

import { 
  useDisclosure, useScrollShadow, useRipple,
  Card, CardHeader, CardBody, Button, Modal, ModalContent
} from "@nextui-org/react";

function useEnhancedCard() {
  const modal = useDisclosure();
  const { ripples, onClick } = useRipple({ color: "primary" });
  const { 
    scrollRef, 
    isTopShadowVisible, 
    isBottomShadowVisible 
  } = useScrollShadow();

  const cardProps = {
    isPressable: true,
    onClick: (e: React.MouseEvent) => {
      onClick(e);
      modal.onOpen();
    },
    className: "relative overflow-hidden",
  };

  return {
    modal,
    scrollRef,
    isTopShadowVisible,
    isBottomShadowVisible,
    ripples,
    cardProps,
  };
}

function EnhancedCardExample() {
  const {
    modal,
    scrollRef,
    isTopShadowVisible,
    isBottomShadowVisible,
    ripples,
    cardProps,
  } = useEnhancedCard();

  const items = Array.from({ length: 20 }, (_, i) => `Item ${i + 1}`);

  return (
    <>
      <Card {...cardProps}>
        <CardHeader>
          <h3>Enhanced Interactive Card</h3>
        </CardHeader>
        <CardBody className="relative">
          {isTopShadowVisible && (
            <div className="absolute top-0 left-0 right-0 h-4 bg-gradient-to-b from-background to-transparent z-10" />
          )}
          
          <div 
            ref={scrollRef}
            className="max-h-32 overflow-y-auto space-y-2"
          >
            {items.map((item) => (
              <div key={item} className="p-2 bg-default-100 rounded">
                {item}
              </div>
            ))}
          </div>
          
          {isBottomShadowVisible && (
            <div className="absolute bottom-0 left-0 right-0 h-4 bg-gradient-to-t from-background to-transparent z-10" />
          )}
          
          {ripples}
        </CardBody>
      </Card>

      <Modal isOpen={modal.isOpen} onOpenChange={modal.onOpenChange}>
        <ModalContent>
          <div className="p-6">
            <h2 className="text-xl font-bold mb-4">Card Details</h2>
            <p>This modal was opened by clicking the card above!</p>
            <Button 
              color="primary" 
              onPress={modal.onClose}
              className="mt-4"
            >
              Close
            </Button>
          </div>
        </ModalContent>
      </Modal>
    </>
  );
}

Advanced Component Extension

Creating sophisticated component extensions using NextUI utilities.

import { 
  extendVariants, forwardRef, cn,
  Button, Card, Badge
} from "@nextui-org/react";

// Extended button with notification capabilities
const NotificationButton = extendVariants(Button, {
  variants: {
    notification: {
      true: "relative",
      false: "",
    },
    notificationColor: {
      primary: "",
      danger: "",
      warning: "",
      success: "",
    },
  },
  defaultVariants: {
    notification: false,
    notificationColor: "primary",
  },
});

// Enhanced card with advanced features
interface EnhancedCardProps {
  children: React.ReactNode;
  isInteractive?: boolean;
  showRipple?: boolean;
  notification?: {
    count: number;
    color?: "primary" | "danger" | "warning" | "success";
  };
  className?: string;
}

const EnhancedCard = forwardRef<HTMLDivElement, EnhancedCardProps>(
  ({ 
    children, 
    isInteractive = false, 
    showRipple = false,
    notification,
    className,
    ...props 
  }, ref) => {
    const { ripples, onClick } = useRipple({
      color: "primary",
      isDisabled: !showRipple,
    });

    return (
      <Card
        ref={ref}
        isPressable={isInteractive}
        className={cn(
          "relative transition-transform",
          isInteractive && "hover:scale-105",
          showRipple && "overflow-hidden",
          className
        )}
        onPress={showRipple ? onClick : undefined}
        {...props}
      >
        {children}
        {showRipple && ripples}
        {notification && (
          <Badge
            content={notification.count}
            color={notification.color}
            className="absolute -top-2 -right-2"
          />
        )}
      </Card>
    );
  }
);

function AdvancedComponentExample() {
  return (
    <div className="space-y-6">
      {/* Enhanced notification button */}
      <NotificationButton
        notification={true}
        notificationColor="danger"
        color="primary"
      >
        Messages
        <Badge 
          content={5} 
          color="danger" 
          className="absolute -top-2 -right-2"
        />
      </NotificationButton>

      {/* Enhanced interactive card */}
      <EnhancedCard
        isInteractive
        showRipple
        notification={{ count: 3, color: "warning" }}
        className="w-64 h-32"
      >
        <div className="p-4">
          <h3 className="font-bold">Interactive Card</h3>
          <p className="text-sm text-default-500">
            Click for ripple effect
          </p>
        </div>
      </EnhancedCard>
    </div>
  );
}

Resizable Panel

Advanced resizable panel component built with Framer Motion for creating flexible layout systems.

interface ResizablePanelProps {
  /** Panel content */
  children: React.ReactNode;
  /** Initial panel size */
  defaultSize?: number;
  /** Minimum panel size */
  minSize?: number;
  /** Maximum panel size */
  maxSize?: number;
  /** Resize direction */
  direction?: "horizontal" | "vertical";
  /** Whether resizing is disabled */
  isDisabled?: boolean;
  /** Panel identifier */
  id?: string;
  /** Custom CSS class */
  className?: string;
  /** Size change handler */
  onSizeChange?: (size: number) => void;
  /** Resize start handler */
  onResizeStart?: () => void;
  /** Resize end handler */
  onResizeEnd?: (size: number) => void;
}

function ResizablePanel(props: ResizablePanelProps): JSX.Element;

/**
 * Hook for managing resizable panel groups
 */
function useResizablePanelGroup(): {
  registerPanel: (id: string, config: ResizablePanelConfig) => void;
  unregisterPanel: (id: string) => void;
  getPanel: (id: string) => ResizablePanelState | undefined;
  resizePanel: (id: string, size: number) => void;
};

interface ResizablePanelConfig {
  defaultSize: number;
  minSize?: number;
  maxSize?: number;
  direction: "horizontal" | "vertical";
}

interface ResizablePanelState {
  id: string;
  size: number;
  minSize: number;
  maxSize: number;
  isResizing: boolean;
}

ResizablePanel Usage Example:

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

function ResizablePanelExample() {
  const [leftSize, setLeftSize] = useState(300);
  const [rightSize, setRightSize] = useState(400);

  return (
    <div className="flex h-96 border border-divider rounded-lg overflow-hidden">
      {/* Left panel */}
      <ResizablePanel
        defaultSize={leftSize}
        minSize={200}
        maxSize={500}
        direction="horizontal"
        onSizeChange={setLeftSize}
        className="border-r border-divider"
      >
        <Card className="h-full shadow-none">
          <CardBody>
            <h3 className="font-semibold mb-2">Left Panel</h3>
            <p className="text-sm text-default-500">
              This panel can be resized horizontally. 
              Current width: {leftSize}px
            </p>
            <div className="mt-4 space-y-2">
              <div className="h-2 bg-primary rounded" />
              <div className="h-2 bg-secondary rounded" />
              <div className="h-2 bg-success rounded" />
            </div>
          </CardBody>
        </Card>
      </ResizablePanel>

      {/* Center panel */}
      <div className="flex-1 border-r border-divider">
        <Card className="h-full shadow-none">
          <CardBody>
            <h3 className="font-semibold mb-2">Fixed Center</h3>
            <p className="text-sm text-default-500">
              This panel takes remaining space between the resizable panels.
            </p>
          </CardBody>
        </Card>
      </div>

      {/* Right panel */}
      <ResizablePanel
        defaultSize={rightSize}
        minSize={250}
        maxSize={600}
        direction="horizontal"
        onSizeChange={setRightSize}
      >
        <Card className="h-full shadow-none">
          <CardBody>
            <h3 className="font-semibold mb-2">Right Panel</h3>
            <p className="text-sm text-default-500">
              Another resizable panel. 
              Current width: {rightSize}px
            </p>
            <div className="mt-4">
              <div className="grid grid-cols-2 gap-2">
                <div className="h-8 bg-warning rounded" />
                <div className="h-8 bg-danger rounded" />
                <div className="h-8 bg-default rounded" />
                <div className="h-8 bg-foreground rounded" />
              </div>
            </div>
          </CardBody>
        </Card>
      </ResizablePanel>
    </div>
  );
}

Additional Utility Exports

// Framer Motion utilities
export { ResizablePanel } from "@nextui-org/framer-utils";

// React Aria utilities  
export { VisuallyHidden } from "@react-aria/visually-hidden";

// Date utilities
export type { CalendarDate, CalendarDateTime, ZonedDateTime, Time } from "@internationalized/date";
export { 
  today, 
  now, 
  getLocalTimeZone,
  isWeekend,
  startOfWeek,
  endOfWeek,
  parseDate,
  parseDateTime,
  parseZonedDateTime,
  parseTime
} from "@internationalized/date";

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