react-collapsible
A React component for building smooth, animated collapsible and accordion sections with full control over triggers, transitions, and styling.
Repository Health
Technical Analysis
react-collapsible is a lightweight React component that wraps any content in an animated collapsible section with a customizable trigger element. Unlike a strict accordion library, it imposes no restriction on how many sections can be open at once — each Collapsible instance manages its own open/closed state independently, while still supporting a controlled open prop and accordionPosition key for building accordion-style UIs where only one section is open at a time.
The component handles CSS height transitions automatically by measuring scrollHeight and toggling between a fixed pixel height and auto, firing onOpening/onClosing at the start of the animation and onOpen/onClose once the transition completes. It exposes a wide surface of props for customizing trigger tag names, transition timing and easing, lazy rendering of children until first open, and CSS class overrides for every internal element, making it straightforward to restyle without fighting the library’s own conventions.
What You Get
- A
<Collapsible>component that wraps any children and renders a trigger plus an animated content container - Automatic ARIA attributes (
aria-expanded,aria-controls,aria-labelledby,role="button"/role="region") and keyboard handling for baseline accessibility - TypeScript type definitions (
index.d.ts) shipped alongside the package - Full CSS class hooks for every rendered element (trigger, content outer, content inner, root) so styling can be layered on with plain CSS
Common Use Cases
- FAQ sections where visitors expand individual answers without a full accordion component
- Accordion navigation built by wiring multiple Collapsible instances together via the
open/accordionPositionprops - Progressive disclosure in long forms, hiding advanced or optional fields behind a collapsible trigger
- Collapsible tree-style navigation menus built by nesting Collapsible components inside one another
Under The Hood
Architecture
The library is a single-file class component (src/Collapsible.js, ~360 lines) that owns all rendering, state-transition, and event-handling logic, with one tiny extracted helper (setInTransition.js) isolating an edge-case fix for zero-height content. State is managed through classic React lifecycle methods (constructor, componentDidUpdate, componentWillUnmount) rather than hooks — height, transition, isClosed, hasBeenOpened, overflow, and inTransition are tracked together and mutated through multiple setState calls triggered by click handlers, controlled open prop changes, and native transitionend events. There is no dependency injection or plugin system; all customization flows through props. The core abstraction — animating between a measured pixel height and auto by listening for onTransitionEnd — is the single mechanism every other behavior depends on, so a change there would ripple through every open/close code path.
Tech Stack
The only runtime dependency is prop-types for runtime prop validation; React and React DOM are peer dependencies supporting a wide range (~15 through ~18). There is no TypeScript source — types ship as a hand-maintained index.d.ts. The build uses Webpack 4 with Babel (preset-env, preset-react, class-properties plugin) to produce a CommonJS dist/index.js, prebuilt via an npm prepare script. Tests run on Jest with Enzyme and the React 16 adapter. Linting uses ESLint with the Babel parser and eslint-plugin-react. CI is a single GitHub Actions workflow that installs dependencies and runs the test suite on push and pull request.
Code Quality
A Jest/Enzyme test suite in __tests__/index.js covers trigger clicks, all six lifecycle callbacks (onOpen/onClose/onOpening/onClosing/onTriggerOpening/onTriggerClosing), a documented zero-height edge case, and the multiple triggerSibling render variants (string, function, element). The reliance on Enzyme with the React 16 adapter is dated — Enzyme is effectively unmaintained and has no official adapter for React 18, despite the package’s peer dependency range extending that far, which limits confidence in the test suite under a modern React runtime. PropTypes provide runtime validation in place of TypeScript, and the separately maintained index.d.ts file could drift from the implementation over time. Naming is consistent and descriptive throughout (openCollapsible/closeCollapsible/continueOpenCollapsible), and there is no swallowed error handling because the component’s scope doesn’t require it.
API Design
The prop API is large but coherent: flat, CSS-transition-shaped props (transitionTime, easing, triggerTagName) ship with sensible defaults, and every internal element has a matching *ClassName prop so consumers can restyle in place without wrapping or overriding internals. Accessibility (ARIA attributes, keyboard Enter/Space handling on the trigger) is built in by default rather than opt-in, which is uncommon for a library this size. The main friction is the callback surface — two near-duplicate pairs (onOpen/onOpening, onClose/onClosing, plus onTriggerOpening/onTriggerClosing) require reading the docs closely to know exactly when each fires, and the accordion pattern (open + accordionPosition + handleTriggerClick) is a manual, string-keyed convention rather than a documented compound-component API.
Used by 2 apps in this directory
GrowthBook
Developer Tools · Analytics · Monitoring
Open source feature flags, A/B testing, and warehouse-native experimentation that queries your existing data infrastructure—no data movement required.
highlight.io
Developer Tools · Analytics · Monitoring
Open-source full-stack monitoring that unifies session replay, error tracking, logging, and distributed tracing so you can stop context-switching between tools.