@kunukn/react-collapse v3.0.14
react-collapse
Collapse component with CSS transition for elements with variable and dynamic height.
react-collapse
Demo
simple - codepen
accordion - codepen
read more - codepen
simple - edit stackblitz
codesandbox - collapsibles
codesandbox expand-all
codesandbox CSS-in-JS integration example
view storybook
CSS required
:warning: ️You need to add style (transition) in your own stylesheet to add animation. Here is an example.
<style>
.collapse-css-transition {
transition: height 280ms cubic-bezier(0.4, 0, 0.2, 1);
}
</style>
Alternatively, you can add it using the transition
prop.
Installation for React 16.8+
- UMD minified ~2.3 kb, gzipped ~1.1 kb
- Module minified ~2.9 kb, gzipped ~1.1 kb
- CJS minified ~2.0 kb, gzipped ~1.0 kb
npm i -D @kunukn/react-collapse
# or
# yarn add -D @kunukn/react-collapse
Installation for React 16.3+
Avoid it if possible. This is no longer maintained.
- UMD minified ~5.8 kb, gzipped ~2.1 kb
npm i -D @kunukn/react-collapse@^1
# or
# yarn add -D @kunukn/react-collapse@^1
Minimal toggle content component example.
// Notice how you import it, changed since ver 3.
import { Collapse } from '@kunukn/react-collapse'
import React from 'react'
export default function MyComponent() {
const [isOpen, setIsOpen] = React.useState(false)
const onToggle = () => setIsOpen((s) => !s)
return (
<div className="my-component">
<button onClick={onToggle}> Toggle </button>
<Collapse
isOpen={isOpen}
transition="height 300ms cubic-bezier(0.4, 0, 0.2, 1)"
>
<p> Hello world </p>
</Collapse>
</div>
)
}
// The possible imports
import { Collapse } from '@kunukn/react-collapse' // UMD
import '@kunukn/react-collapse/dist/react-collapse.css' // CSS
import type { CollapseProps } from '@kunukn/react-collapse/dist/react-collapse.d.ts' // TS
const { Collapse } = require('@kunukn/react-collapse/dist/react-collapse.cjs') // CommonJS
Properties
Prop | Type | Default |
---|---|---|
isOpen | boolean | false |
children | node | function | |
render | function | |
className | string | collapse-css-transition |
transition | string | |
elementType | string | div |
collapseHeight | string | 0px |
onChange | function | |
onInit | function | |
addState | boolean | false |
noAnim | boolean | false |
overflowOnExpanded | boolean | false |
isOpen
: boolean
Expands or collapses content.
children
: node | function
Render the children.
const MyComponent = ({ isOpen }) => (
<Collapse isOpen={isOpen}>
<p>Paragraph of text.</p>
<p>Another paragraph is also OK.</p>
<p>Images and any other content are ok too.</p>
<img src="cutecat.gif" />
</Collapse>
)
Render content using the render-props pattern.
const MyComponent = ({ isOpen }) => (
<Collapse isOpen={isOpen}>
{(state) => (
<div className={`using-collapse-state-to-add-css-class ${state}`}>
<p>I know the collapse state: {state}</p>
</div>
)}
</Collapse>
)
render
: function
Render content using the render-props pattern.
const MyComponent = ({ isOpen }) => {
const render = (state) => (
<div className={`using-collapse-state-to-add-css-class ${state}`}>
<p>I know the collapse state: {state}</p>
</div>
)
return <Collapse isOpen={isOpen} render={render} />
}
There are four possible collapse states: collapsed
, collapsing
, expanded
, expanding
.
className
: string
You can specify a custom className. The default value is collapse-css-transition
. Remember to add CSS transition if a className is provided.
transition
: string
You can also specify a CSS transition inline by using the transition
prop.
const MyComponent = ({ isOpen, duration = '290ms' }) => (
<Collapse
transition={`height ${duration} cubic-bezier(.4, 0, .2, 1)`}
isOpen={isOpen}
>
<p>Paragraph of text</p>
</Collapse>
)
elementType
: string
You can specify the HTML element type for the collapse component. By default, the element type is a div
element.
const MyComponent = ({ isOpen }) => (
<Collapse elementType="article" isOpen={isOpen}>
<p>Paragraph of text inside an article element</p>
</Collapse>
)
collapseHeight
: string
You can specify the collapse height in CSS unit to partially show some content.
const MyComponent = ({ isOpen }) => (
<Collapse collapseHeight="40px" isOpen={isOpen}>
<p>A long paragraph of text inside an article element</p>
</Collapse>
)
onChange
: function
Callback function for when the transition changes.
const MyComponent = ({ isOpen }) => {
const onChange = ({ state, style }) => {
/*
state: string = the state of the collapse component.
style: object = styles that are applied to the component.
*/
}
return (
<Collapse onChange={onChange} isOpen={isOpen}>
<p>A long paragraph of text inside an article element</p>
</Collapse>
)
}
onInit
: function
Similar to onChange but only invoked on DOM mounted. This is an example that starts collapsed and expands on mount.
const MyComponent = () => {
const [isOpen, setIsOpen] = React.useState(false)
const onInit = ({ state, style, node }) => {
/*
node: HTMLElement = the DOM node of the component.
*/
setIsOpen(true)
}
return (
<div>
<button onClick={() => setIsOpen((state) => !state)}> Toggle </button>
<Collapse onInit={onInit} isOpen={isOpen}>
<p>A long paragraph of text inside an article element</p>
</Collapse>
</div>
)
}
addState
: boolean
If added, then one of the class names will be appended to the component depending on the state.
--c-collapsed
--c-collapsing
--c-expanded
--c-expanding
noAnim
: boolean
If added, then there will be no collapse animation. State changes between collapsed
and expanded
.
overflowOnExpanded
: boolean
If added, then overflow: hidden
style will not be added when the state is expanded
.
Custom props
Collapse
applies custom props such as aria-
and data-
attributes to the component's rendered DOM element. For example, this can be used to set the aria-hidden
attribute:
const MyComponent = ({ isOpen }) => (
<Collapse aria-hidden={isOpen ? 'false' : 'true'} isOpen={isOpen}>
<p>Paragraph of text</p>
</Collapse>
)
Or you could specify a specific transitionDuration.
const collapseStyles = { transitionDuration: '270ms' }
const MyComponent = ({ isOpen }) => (
<Collapse style={collapseStyles} isOpen={isOpen}>
<p>Paragraph of text</p>
</Collapse>
)
Development
To run development
npm start
git clone [repo]
cd [repo]
npm i
npm start
- To develop and play around:
npm start
- To build the bundle:
npm run build
CDN
https://unpkg.com/@kunukn/react-collapse/
<link
rel="stylesheet"
href="https://unpkg.com/@kunukn/react-collapse/dist/react-collapse.css"
/>
<!-- UMD -->
<script src="https://unpkg.com/@kunukn/react-collapse"></script>
NPM
https://www.npmjs.com/package/@kunukn/react-collapse
Supported browsers
Modern browsers (Edge, Firefox, Chrome, Safari, etc).
Supported React versions
- React version 16.3+ : use Collapse version 1
- React version 16.8+ : use Collapse version 2+
Used React 16.3 life-cycles
- render (uses the style states to invoke CSS transition)
- componentDidMount (initial expanded or collapsed state)
- getDerivedStateFromProps (detect if isOpen props have changed and apply a new collapse state)
- componentDidUpdate (update style states from the four possible collapse states)
Used React 16.8+ hooks
- useState
- useEffect
- useRef
- useCallback
- useReducer
Design goals
- let the browser handle the animation using CSS height transition
- minimal in file size
- minimalistic API - only have a Collapse component which updates on isOpen props
- flexible - provide your own markup, styling and easing
- interruptible - can be reversed during movement
- inert - when collapsed you should tab over the collapsed component
- availability - from cdn or npm install
- collapsible on height only
This was created with heavy inspiration from
https://github.com/SparebankenVest/react-css-collapse 🎆
A version also exists for Vue
14 days ago
15 days ago
15 days ago
17 days ago
17 days ago
17 days ago
17 days ago
18 days ago
17 days ago
20 days ago
20 days ago
20 days ago
20 days ago
20 days ago
20 days ago
1 year ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago