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

animation.mddocs/

Animation and Motion

RC-Collapse integrates with rc-motion to provide smooth expand and collapse animations. The animation system supports extensive customization through motion configuration props.

Motion Configuration

interface CSSMotionProps {
  motionName?: string;
  motionAppear?: boolean;
  motionEnter?: boolean;
  motionLeave?: boolean;
  motionLeaveImmediately?: boolean;
  motionDeadline?: number;
  removeOnLeave?: boolean;
  leavedClassName?: string;
  onAppearStart?: MotionEventHandler;
  onEnterStart?: MotionEventHandler;
  onLeaveStart?: MotionEventHandler;
  onAppearActive?: MotionEventHandler;
  onEnterActive?: MotionEventHandler;
  onLeaveActive?: MotionEventHandler;
  onAppearEnd?: MotionEventHandler;
  onEnterEnd?: MotionEventHandler;
  onLeaveEnd?: MotionEventHandler;
}

type MotionEventHandler = (
  element: HTMLElement,
  event?: React.TransitionEvent | React.AnimationEvent
) => React.CSSProperties | void;

interface MotionEvent {
  deadline?: boolean;
  target?: HTMLElement;
}

Animation Properties

Motion Control

  • motionName: string - CSS class prefix for motion states
  • motionAppear: boolean - Enable appear animation (default: true)
  • motionEnter: boolean - Enable enter animation (default: true)
  • motionLeave: boolean - Enable leave animation (default: true)
  • motionLeaveImmediately: boolean - Start leave animation immediately
  • motionDeadline: number - Maximum animation duration in milliseconds
  • removeOnLeave: boolean - Remove element from DOM after leave animation

CSS Classes

  • leavedClassName: string - CSS class applied to hidden panels (default: 'rc-collapse-content-hidden')

Event Handlers

Animation lifecycle event handlers that allow custom animation control:

  • onAppearStart: Fired when appear animation starts
  • onEnterStart: Fired when enter animation starts
  • onLeaveStart: Fired when leave animation starts
  • onAppearActive: Fired during appear animation
  • onEnterActive: Fired during enter animation
  • onLeaveActive: Fired during leave animation
  • onAppearEnd: Fired when appear animation ends
  • onEnterEnd: Fired when enter animation ends
  • onLeaveEnd: Fired when leave animation ends

Usage Examples

Basic Animation Setup

import Collapse from "rc-collapse";

const BasicAnimation = () => {
  const openMotion = {
    motionName: 'rc-collapse-motion',
    motionAppear: false,
    motionEnter: true,
    motionLeave: true,
  };

  const items = [
    { key: '1', label: 'Animated Panel', children: 'Content with animation' },
  ];

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

Custom Animation Duration

import Collapse from "rc-collapse";

const CustomDuration = () => {
  const openMotion = {
    motionName: 'custom-collapse',
    motionDeadline: 300, // 300ms max duration
    onEnterStart: (element) => {
      element.style.transition = 'height 0.3s ease-out';
      return { height: 0 };
    },
    onEnterActive: (element) => {
      return { height: element.scrollHeight };
    },
    onLeaveStart: (element) => {
      return { height: element.scrollHeight };
    },
    onLeaveActive: () => {
      return { height: 0 };
    },
  };

  const items = [
    { key: '1', label: 'Custom Duration Panel', children: 'Animated content' },
  ];

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

Smooth Height Animation

import Collapse from "rc-collapse";

const SmoothHeightAnimation = () => {
  const smoothMotion = {
    motionName: 'smooth-collapse',
    onEnterStart: (element: HTMLElement) => {
      element.style.height = '0px';
      element.style.opacity = '0';
      return {
        height: 0,
        opacity: 0,
      };
    },
    onEnterActive: (element: HTMLElement) => {
      element.style.transition = 'height 0.2s ease, opacity 0.2s ease';
      return {
        height: `${element.scrollHeight}px`,
        opacity: 1,
      };
    },
    onLeaveStart: (element: HTMLElement) => {
      return {
        height: `${element.scrollHeight}px`,
        opacity: 1,
      };
    },
    onLeaveActive: () => {
      return {
        height: 0,
        opacity: 0,
      };
    },
  };

  const items = [
    { key: '1', label: 'Smooth Animation', children: 'Smoothly animated content' },
  ];

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

No Animation (Instant Toggle)

import Collapse from "rc-collapse";

const NoAnimation = () => {
  const noMotion = {
    motionName: '',
    motionAppear: false,
    motionEnter: false,
    motionLeave: false,
  };

  const items = [
    { key: '1', label: 'Instant Toggle', children: 'No animation content' },
  ];

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

Advanced Animation with Callbacks

import Collapse from "rc-collapse";

const AdvancedAnimation = () => {
  const advancedMotion = {
    motionName: 'advanced-collapse',
    motionDeadline: 500,
    onEnterStart: (element: HTMLElement) => {
      console.log('Panel opening started');
      element.style.transformOrigin = 'top';
      return {
        transform: 'scaleY(0)',
        opacity: 0,
      };
    },
    onEnterActive: (element: HTMLElement) => {
      element.style.transition = 'transform 0.3s ease, opacity 0.3s ease';
      return {
        transform: 'scaleY(1)',
        opacity: 1,
      };
    },
    onEnterEnd: () => {
      console.log('Panel opening completed');
    },
    onLeaveStart: (element: HTMLElement) => {
      console.log('Panel closing started');
      return {
        transform: 'scaleY(1)',
        opacity: 1,
      };
    },
    onLeaveActive: () => {
      return {
        transform: 'scaleY(0)',
        opacity: 0,
      };
    },
    onLeaveEnd: () => {
      console.log('Panel closing completed');
    },
  };

  const items = [
    { key: '1', label: 'Advanced Animation', children: 'Advanced animated content' },
  ];

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

CSS Classes and Styling

Default Motion Classes

RC-Collapse applies the following CSS classes during animations:

/* Panel content container */
.rc-collapse-content {
  overflow: hidden;
}

/* Hidden panel state */
.rc-collapse-content-hidden {
  display: none;
}

/* Active panel state */
.rc-collapse-content-active {
  /* Panel is visible and expanded */
}

/* Inactive panel state */  
.rc-collapse-content-inactive {
  /* Panel is hidden or collapsed */
}

Custom Motion CSS

/* Custom animation example */
.custom-collapse-motion-enter {
  opacity: 0;
  transform: translateY(-10px);
}

.custom-collapse-motion-enter-active {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 0.2s, transform 0.2s;
}

.custom-collapse-motion-leave {
  opacity: 1;
  transform: translateY(0);
}

.custom-collapse-motion-leave-active {
  opacity: 0;
  transform: translateY(-10px);
  transition: opacity 0.2s, transform 0.2s;
}

Performance Considerations

Animation Performance Tips

  • Use transform and opacity properties for better performance
  • Avoid animating height directly when possible
  • Consider using will-change CSS property for smooth animations
  • Use motionDeadline to prevent long-running animations

Memory Management

const optimizedMotion = {
  motionName: 'optimized-collapse',
  removeOnLeave: true, // Remove from DOM after animation
  motionDeadline: 300, // Limit animation duration
};

Accessibility and Animation

Respecting User Preferences

import Collapse from "rc-collapse";

const AccessibleAnimation = () => {
  // Respect user's motion preferences
  const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  
  const respectfulMotion = prefersReducedMotion 
    ? {
        motionName: '',
        motionEnter: false,
        motionLeave: false,
      }
    : {
        motionName: 'smooth-collapse',
        motionEnter: true,
        motionLeave: true,
      };

  const items = [
    { key: '1', label: 'Accessible Panel', children: 'Respects motion preferences' },
  ];

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

Animation and Screen Readers

The animation system is designed to work with screen readers:

  • Content visibility changes are announced properly
  • ARIA states are updated before animations start
  • Focus management is maintained during animations

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