CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-rc-collapse

React collapsible panel component with accordion support and extensive customization options

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

panel-configuration.mddocs/

Panel Configuration

Panel configuration defines the structure and behavior of individual collapsible sections within a Collapse component. The modern approach uses the items prop with ItemType objects.

ItemType Interface

interface ItemType {
  key?: React.Key;
  label?: React.ReactNode;
  children?: React.ReactNode;
  collapsible?: CollapsibleType;
  onItemClick?: (panelKey: React.Key) => void;
  destroyInactivePanel?: boolean;
  className?: string;
  style?: object;
  classNames?: Partial<Record<SemanticName, string>>;
  styles?: Partial<Record<SemanticName, React.CSSProperties>>;
  extra?: React.ReactNode;
  forceRender?: boolean;
  showArrow?: boolean;
  headerClass?: string;
  ref?: React.RefObject<HTMLDivElement>;
}

type CollapsibleType = 'header' | 'icon' | 'disabled';
type SemanticName = 'header' | 'title' | 'body' | 'icon';

Configuration Properties

Essential Properties

  • key: React.Key - Unique identifier for the panel (defaults to array index)
  • label: React.ReactNode - Panel header content (text, JSX, or React components)
  • children: React.ReactNode - Panel body content

Behavior Configuration

  • collapsible: CollapsibleType - Override global collapsible behavior for this panel
    • 'header': Click header area to toggle
    • 'icon': Click expand icon only to toggle
    • 'disabled': Panel cannot be toggled
  • onItemClick: (panelKey: React.Key) => void - Panel-specific click handler
  • destroyInactivePanel: boolean - Override global destroy behavior for this panel
  • forceRender: boolean - Always render panel content even when inactive
  • showArrow: boolean - Show/hide expand arrow for this panel (default: true)
  • ref: React.RefObject<HTMLDivElement> - React ref for the panel element

Styling Configuration

  • className: string - Custom CSS class for the panel container
  • style: object - Inline styles for the panel container
  • headerClass: string - Custom CSS class for the panel header
  • classNames: Partial<Record<SemanticName, string>> - Semantic CSS classes
  • styles: Partial<Record<SemanticName, React.CSSProperties>> - Semantic inline styles
  • extra: React.ReactNode - Additional content rendered in the header area

Usage Examples

Basic Panel Configuration

import Collapse from "rc-collapse";

const BasicPanels = () => {
  const items = [
    {
      key: 'panel1',
      label: 'First Panel',
      children: <div>This is the content of the first panel</div>,
    },
    {
      key: 'panel2',
      label: 'Second Panel',
      children: 'Simple text content for second panel',
    },
  ];

  return <Collapse items={items} />;
};

Advanced Panel Configuration

import Collapse from "rc-collapse";

const AdvancedPanels = () => {
  const items = [
    {
      key: 'interactive',
      label: (
        <div onKeyDown={(e) => e.stopPropagation()}>
          <input placeholder="This input won't trigger panel toggle" />
        </div>
      ),
      children: 'Panel with interactive header',
      showArrow: true,
    },
    {
      key: 'disabled',
      label: 'Disabled Panel',
      children: 'This panel cannot be toggled',
      collapsible: 'disabled',
    },
    {
      key: 'icon-only',
      label: 'Icon Only Toggle',
      children: 'Click the arrow icon to toggle this panel',
      collapsible: 'icon',
    },
  ];

  return <Collapse items={items} />;
};

Panel with Extra Content

import Collapse from "rc-collapse";

const PanelWithExtra = () => {
  const items = [
    {
      key: 'with-extra',
      label: 'Panel with Extra Content',
      children: 'Main panel content here',
      extra: (
        <button onClick={(e) => {
          e.stopPropagation();
          console.log('Extra button clicked');
        }}>
          Action
        </button>
      ),
    },
  ];

  return <Collapse items={items} />;
};

Semantic Styling

import Collapse from "rc-collapse";

const SemanticStyling = () => {
  const items = [
    {
      key: 'styled',
      label: 'Styled Panel',
      children: 'Content with custom styling',
      classNames: {
        header: 'custom-header-class',
        title: 'custom-title-class',
        body: 'custom-body-class',
        icon: 'custom-icon-class',
      },
      styles: {
        header: { backgroundColor: '#f0f0f0', padding: '12px' },
        title: { fontWeight: 'bold', color: '#333' },
        body: { padding: '16px', border: '1px solid #ddd' },
        icon: { color: '#1890ff' },
      },
    },
  ];

  return <Collapse items={items} />;
};

Performance-Optimized Panels

import Collapse from "rc-collapse";

const PerformancePanels = () => {
  const items = [
    {
      key: 'heavy-content',
      label: 'Heavy Content Panel',
      children: <ExpensiveComponent />,
      destroyInactivePanel: true, // Destroy when inactive
    },
    {
      key: 'always-rendered',
      label: 'Always Rendered Panel',
      children: <ImportantComponent />,
      forceRender: true, // Always keep in DOM
    },
    {
      key: 'lazy-content',
      label: 'Lazy Content Panel',
      children: <LazyComponent />,
      // Default behavior: render when first opened
    },
  ];

  return <Collapse items={items} />;
};

Custom Click Handlers

import Collapse from "rc-collapse";

const CustomClickHandlers = () => {
  const handlePanelClick = (panelKey: React.Key) => {
    console.log(`Panel ${panelKey} was clicked`);
    // Custom logic here
  };

  const items = [
    {
      key: 'tracked',
      label: 'Tracked Panel',
      children: 'This panel logs clicks',
      onItemClick: handlePanelClick,
    },
    {
      key: 'analytics',
      label: 'Analytics Panel',
      children: 'This panel sends analytics events',
      onItemClick: (key) => {
        // Send analytics event
        analytics.track('panel_toggled', { panelKey: key });
      },
    },
  ];

  return <Collapse items={items} />;
};

Panel Key Management

Key Generation

  • If key is not provided, the panel's array index is used as the key
  • Keys are converted to strings internally for consistency
  • Use meaningful, stable keys for better performance and state management

Key Best Practices

// Good: Meaningful, stable keys
const goodItems = [
  { key: 'user-profile', label: 'Profile', children: '...' },
  { key: 'user-settings', label: 'Settings', children: '...' },
];

// Avoid: Index-based keys when order might change
const avoidItems = [
  { key: 0, label: 'Dynamic Item', children: '...' },
  { key: 1, label: 'Another Item', children: '...' },
];

Migration from Legacy Panel Components

// Legacy approach (deprecated)
<Collapse>
  <Panel header="Panel 1" key="1">Content 1</Panel>
  <Panel header="Panel 2" key="2">Content 2</Panel>
</Collapse>

// Modern approach (recommended)
<Collapse
  items={[
    { key: '1', label: 'Panel 1', children: 'Content 1' },
    { key: '2', label: 'Panel 2', children: 'Content 2' },
  ]}
/>

Install with Tessl CLI

npx tessl i tessl/npm-rc-collapse

docs

animation.md

core-component.md

index.md

legacy-panel.md

panel-configuration.md

tile.json