or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

components.mdhooks.mdindex.md
tile.json

hooks.mddocs/

State Management Hooks

React hooks providing accordion state logic, item management, and context access for building custom accordion implementations.

Capabilities

useAccordion

Root hook providing all state and focus management logic for accordion items.

/**
 * useAccordion hook provides all the state and focus management logic
 * for accordion items.
 */
declare function useAccordion(props: UseAccordionProps): UseAccordionReturn;

interface UseAccordionProps {
  /** If true, multiple accordion items can be expanded at once */
  allowMultiple?: boolean;
  /** If true, any expanded accordion item can be collapsed again */
  allowToggle?: boolean;
  /** The index(es) of the expanded accordion item */
  index?: number | number[];
  /** The initial index(es) of the expanded accordion item */
  defaultIndex?: number | number[];
  /** The callback invoked when accordion items are expanded or collapsed */
  onChange?(expandedIndex: number | number[]): void;
}

interface UseAccordionReturn {
  /** Current expanded index(es) */
  index: number | number[];
  /** Function to update expanded index(es) */
  setIndex: React.Dispatch<React.SetStateAction<number | number[]>>;
  /** Props for the root accordion element */
  htmlProps: React.HTMLAttributes<HTMLElement>;
  /** Function to get props for child accordion items */
  getAccordionItemProps: (idx: number | null) => {
    isOpen: boolean;
    onChange: (isOpen: boolean) => void;
  };
  /** Currently focused accordion item index */
  focusedIndex: number;
  /** Function to update focused index */
  setFocusedIndex: React.Dispatch<React.SetStateAction<number>>;
  /** Descendant management utilities for focus control */
  descendants: DescendantsManager<HTMLButtonElement>;
}

Usage Examples:

import { useAccordion } from "@chakra-ui/accordion";

// Basic custom accordion implementation
function CustomAccordion({ children, ...props }) {
  const { htmlProps, getAccordionItemProps, descendants } = useAccordion(props);
  
  return (
    <AccordionDescendantsProvider value={descendants}>
      <div {...htmlProps} className="custom-accordion">
        {children}
      </div>
    </AccordionDescendantsProvider>
  );
}

// Controlled accordion with external state
function ControlledCustomAccordion() {
  const [activeIndex, setActiveIndex] = React.useState(-1);
  
  const accordion = useAccordion({
    index: activeIndex,
    onChange: setActiveIndex,
    allowToggle: true
  });
  
  // Use accordion.getAccordionItemProps() for each item
  return (
    <div {...accordion.htmlProps}>
      {/* Custom accordion items */}
    </div>
  );
}

// Multi-select accordion
function MultiSelectAccordion() {
  const accordion = useAccordion({
    allowMultiple: true,
    defaultIndex: [0, 2]
  });
  
  return (
    <div {...accordion.htmlProps}>
      {/* Multiple items can be open simultaneously */}
    </div>
  );
}

useAccordionItem

Hook providing open/close functionality for individual accordion items.

/**
 * useAccordionItem - React hook that provides the open/close functionality
 * for an accordion item and its children
 */
declare function useAccordionItem(props: UseAccordionItemProps): UseAccordionItemReturn;

interface UseAccordionItemProps {
  /** If true, the accordion item will be disabled */
  isDisabled?: boolean;
  /** If true, the accordion item will be focusable */
  isFocusable?: boolean;
  /** A unique id for the accordion item */
  id?: string;
}

interface UseAccordionItemReturn {
  /** Whether the accordion item is currently open */
  isOpen: boolean;
  /** Whether the accordion item is disabled */
  isDisabled?: boolean;
  /** Whether the accordion item is focusable */
  isFocusable?: boolean;
  /** Function to expand the accordion item */
  onOpen: () => void;
  /** Function to collapse the accordion item */
  onClose: () => void;
  /** Function to get props for the accordion button element */
  getButtonProps: (
    props?: React.HTMLAttributes<HTMLElement>,
    ref?: React.Ref<HTMLButtonElement>
  ) => React.ComponentProps<"button">;
  /** Function to get props for the accordion panel element */
  getPanelProps: <T>(
    props?: React.HTMLAttributes<T>,
    ref?: React.Ref<T>
  ) => React.HTMLAttributes<T> & React.RefAttributes<T>;
  /** Additional HTML props for the accordion item container */
  htmlProps: React.HTMLAttributes<HTMLElement>;
}

Usage Examples:

import { useAccordionItem } from "@chakra-ui/accordion";

// Custom accordion item implementation
function CustomAccordionItem({ children, ...props }) {
  const {
    isOpen,
    isDisabled,
    onOpen,
    onClose,
    getButtonProps,
    getPanelProps,
    htmlProps
  } = useAccordionItem(props);
  
  return (
    <div {...htmlProps} className="custom-accordion-item">
      <button {...getButtonProps()}>
        {isOpen ? "Collapse" : "Expand"} Item
      </button>
      <div {...getPanelProps()}>
        {children}
      </div>
    </div>
  );
}

// Accordion item with custom controls
function AccordionItemWithControls({ title, children, ...props }) {
  const accordionItem = useAccordionItem(props);
  
  return (
    <div {...accordionItem.htmlProps}>
      <div className="item-header">
        <button {...accordionItem.getButtonProps()}>
          {title}
        </button>
        <div className="controls">
          <button onClick={accordionItem.onOpen} disabled={accordionItem.isOpen}>
            Open
          </button>
          <button onClick={accordionItem.onClose} disabled={!accordionItem.isOpen}>
            Close
          </button>
        </div>
      </div>
      <div {...accordionItem.getPanelProps()}>
        {children}
      </div>
    </div>
  );
}

// Disabled accordion item
function DisabledAccordionItem({ children }) {
  const accordionItem = useAccordionItem({ 
    isDisabled: true,
    isFocusable: true // Still focusable for accessibility
  });
  
  return (
    <div {...accordionItem.htmlProps} className="disabled-item">
      <button {...accordionItem.getButtonProps()}>
        Disabled Item (Focusable)
      </button>
      <div {...accordionItem.getPanelProps()}>
        {children}
      </div>
    </div>
  );
}

useAccordionContext

Hook to access the accordion context for accessing root-level state and methods.

/**
 * Hook to access accordion context (root level state)
 */
declare function useAccordionContext(): AccordionContext;

interface AccordionContext {
  /** Current expanded index(es) */
  index: number | number[];
  /** Function to update expanded index(es) */
  setIndex: React.Dispatch<React.SetStateAction<number | number[]>>;
  /** Function to get props for child accordion items */
  getAccordionItemProps: (idx: number | null) => {
    isOpen: boolean;
    onChange: (isOpen: boolean) => void;
  };
  /** Currently focused accordion item index */
  focusedIndex: number;
  /** Function to update focused index */
  setFocusedIndex: React.Dispatch<React.SetStateAction<number>>;
  /** Whether motion/animations are reduced */
  reduceMotion: boolean;
}

Usage Examples:

import { useAccordionContext } from "@chakra-ui/accordion";

// Custom component that accesses accordion state
function AccordionStatus() {
  const { index, focusedIndex, reduceMotion } = useAccordionContext();
  
  return (
    <div className="accordion-status">
      <p>Open items: {Array.isArray(index) ? index.join(", ") : index}</p>
      <p>Focused item: {focusedIndex}</p>
      <p>Animations: {reduceMotion ? "Disabled" : "Enabled"}</p>
    </div>
  );
}

// Custom accordion item that uses context directly
function ContextAwareAccordionItem({ itemIndex, children }) {
  const { getAccordionItemProps, setFocusedIndex } = useAccordionContext();
  const { isOpen, onChange } = getAccordionItemProps(itemIndex);
  
  return (
    <div className="context-aware-item">
      <button 
        onClick={() => {
          onChange(!isOpen);
          setFocusedIndex(itemIndex);
        }}
      >
        {isOpen ? "Close" : "Open"} Item {itemIndex}
      </button>
      {isOpen && <div>{children}</div>}
    </div>
  );
}

useAccordionItemState

Hook to get the current state and actions of an accordion item.

/**
 * React hook to get the state and actions of an accordion item
 */
declare function useAccordionItemState(): AccordionItemState;

interface AccordionItemState {
  /** Whether the accordion item is currently open */
  isOpen: boolean;
  /** Function to close the accordion item */
  onClose: () => void;
  /** Whether the accordion item is disabled */
  isDisabled?: boolean;
  /** Function to open the accordion item */
  onOpen: () => void;
}

Usage Examples:

import { useAccordionItemState } from "@chakra-ui/accordion";

// Component that displays accordion item state
function AccordionItemStateDisplay() {
  const { isOpen, isDisabled, onOpen, onClose } = useAccordionItemState();
  
  return (
    <div className="item-state-display">
      <p>Status: {isOpen ? "Open" : "Closed"}</p>
      <div className="state-controls">
        <button onClick={onOpen} disabled={isOpen || isDisabled}>
          Open
        </button>
        <button onClick={onClose} disabled={!isOpen || isDisabled}>
          Close
        </button>
      </div>
    </div>
  );
}

// Custom accordion panel with state-aware content
function StateAwarePanel({ children }) {
  const { isOpen } = useAccordionItemState();
  
  return (
    <div className={`panel ${isOpen ? "panel-open" : "panel-closed"}`}>
      <div className="panel-content">
        {children}
      </div>
      <div className="panel-footer">
        <small>Panel is {isOpen ? "expanded" : "collapsed"}</small>
      </div>
    </div>
  );
}

// Conditional rendering based on state
function ConditionalContent() {
  const { isOpen } = useAccordionItemState();
  
  return (
    <div>
      {isOpen ? (
        <div>This content only shows when expanded</div>
      ) : (
        <div>This content only shows when collapsed</div>
      )}
    </div>
  );
}

useAccordionStyles

Hook to access accordion styling context from the Chakra UI theme system.

/**
 * Hook to access accordion styling context 
 */
declare function useAccordionStyles(): Record<string, SystemStyleObject>;

interface SystemStyleObject {
  [property: string]: any;
}

Usage Examples:

import { useAccordionStyles } from "@chakra-ui/accordion";

// Custom component that uses accordion styles
function StyledAccordionItem() {
  const styles = useAccordionStyles();
  
  return (
    <div style={styles.container}>
      <button style={styles.button}>
        Custom Styled Button
      </button>
      <div style={styles.panel}>
        Custom Styled Panel
      </div>
    </div>
  );
}

// Component that extends default styles
function ExtendedStyledItem() {
  const styles = useAccordionStyles();
  
  const customButtonStyles = {
    ...styles.button,
    backgroundColor: "blue.500",
    color: "white"
  };
  
  return (
    <div style={styles.container}>
      <button style={customButtonStyles}>
        Extended Styled Button
      </button>
      <div style={styles.panel}>
        Panel with default styles
      </div>
    </div>
  );
}

Context Providers

/**
 * Context provider for accordion state
 */
declare const AccordionProvider: React.ComponentType<{
  value: AccordionContext;
  children: React.ReactNode;
}>;

/**
 * Context provider for accordion descendant management
 */
declare const AccordionDescendantsProvider: React.ComponentType<{
  value: DescendantsManager<HTMLButtonElement>;
  children: React.ReactNode;
}>;

interface DescendantsManager<T extends HTMLElement> {
  descendants: Map<HTMLElement, DescendantOptions>;
  register: (node: T | null) => void;
  unregister: (node: T) => void;
  destroy: () => void;
  assignIndex: (node: T) => number;
  count: () => number;
  enabledCount: () => number;
  values: () => Descendant<T>[];
  item: (index: number) => Descendant<T> | undefined;
  enabled: () => Descendant<T>[];
  first: () => Descendant<T> | undefined;
  last: () => Descendant<T> | undefined;
  indexOf: (node: T) => number;
  next: (index: number, loop?: boolean) => Descendant<T> | undefined;
  prev: (index: number, loop?: boolean) => Descendant<T> | undefined;
  nextEnabled: (index: number, loop?: boolean) => Descendant<T> | undefined;
  prevEnabled: (index: number, loop?: boolean) => Descendant<T> | undefined;
  firstEnabled: () => Descendant<T> | undefined;
  lastEnabled: () => Descendant<T> | undefined;
}