UNPKG

10 kBMarkdownView Raw
1# react-collapse
2
3Collapse component with CSS transition for elements with variable and dynamic height.
4
5[![npm version](https://img.shields.io/npm/v/@kunukn/react-collapse.svg?style=flat-square)](https://www.npmjs.com/package/@kunukn/react-collapse)
6[![npm downloads](https://img.shields.io/npm/dm/@kunukn/react-collapse.svg?style=flat-square)](https://www.npmjs.com/package/@kunukn/react-collapse)
7[![gzip](https://img.shields.io/bundlephobia/minzip/@kunukn/react-collapse.svg)](https://bundlephobia.com/result?p=@kunukn/react-collapse)
8[![license](https://img.shields.io/github/license/kunukn/react-collapse.svg)](https://github.com/kunukn/react-collapse/blob/master/LICENSE)
9
10react-collapse
11
12![logo](logo/collapse.svg "logo")
13
14# Demo
15
16- <a href="https://codepen.io/kunukn/full/ebMryW" target="_blank">simple - codepen</a>
17- <a href="https://codepen.io/kunukn/full/xmjRNo" target="_blank">accordion - codepen</a>
18- <a href="https://codepen.io/kunukn/full/JwmEYL" target="_blank">read more - codepen</a>
19- <a href="https://codesandbox.io/s/k1439yw2v5" target="_blank">codesandbox - collapsibles</a>
20- <a href="https://codesandbox.io/s/react-collapse-expand-all-collapse-all-0h4mc">codesandbox expand-all</a>
21- <a href="https://codesandbox.io/s/collapse-with-emotion-css-prototype-euqy2">codesandbox CSS-in-JS integration example</a>
22- <a href="https://kunukn.github.io/react-collapse" target="_blank">view storybook</a>
23
24# CSS required
25
26:warning: ️You need to add style (transition) in your own stylesheet to add animation. Here is an example.
27
28```html
29<style>
30 .collapse-css-transition {
31 transition: height 280ms cubic-bezier(0.4, 0, 0.2, 1);
32 }
33</style>
34```
35
36Alternatively you can add it using the `transition` prop.
37
38## Installation for React 16.8+
39
40UMD minified 3.8kb, gzipped 1.7kb
41
42```bash
43npm i @kunukn/react-collapse
44# or
45# yarn add @kunukn/react-collapse
46```
47
48## Installation for React 16.3+
49
50UMD minified 5.8kb, gzipped 2.1kb
51
52```bash
53npm i @kunukn/react-collapse@^1
54# or
55# yarn add @kunukn/react-collapse@^1
56```
57
58```jsx
59import Collapse from "@kunukn/react-collapse";
60// or with require syntax
61// const Collapse = require("@kunukn/react-collapse");
62
63const MyComponent = () => (
64 <Collapse isOpen={true || false}>
65 <div>Your content</div>
66 </Collapse>
67);
68```
69
70## Properties
71
72| Prop | Type | Default |
73| ------------------ | ---------------- | ----------------------- |
74| isOpen | boolean | false |
75| children | node \| function | |
76| render | function | |
77| className | string | collapse-css-transition |
78| transition | string | |
79| elementType | string | div |
80| collapseHeight | string | 0px |
81| onChange | function | |
82| onInit | function | |
83| addState | boolean | false |
84| noAnim | boolean | false |
85| overflowOnExpanded | boolean | false |
86
87<br>
88
89#### `isOpen` : boolean
90
91Expands or collapses content.
92
93#### `children` : node | function
94
95Render the children.
96
97```jsx
98const MyComponent = ({ isOpen }) => (
99 <Collapse isOpen={isOpen}>
100 <p>Paragraph of text.</p>
101 <p>Another paragraph is also OK.</p>
102 <p>Images and any other content are ok too.</p>
103 <img src="cutecat.gif" />
104 </Collapse>
105);
106```
107
108Render content using the [render-props pattern](https://reactjs.org/docs/render-props.html).
109
110```jsx
111const MyComponent = ({ isOpen }) => (
112 <Collapse isOpen={isOpen}>
113 {state => (
114 <div className={`using-collapse-state-to-add-css-class ${state}`}>
115 <p>I know the collapse state: {state}</p>
116 </div>
117 )}
118 </Collapse>
119);
120```
121
122#### `render` : function
123
124Render content using the render-props pattern.
125
126```jsx
127const MyComponent = ({ isOpen }) => {
128 const render = state => (
129 <div className={`using-collapse-state-to-add-css-class ${state}`}>
130 <p>I know the collapse state: {state}</p>
131 </div>
132 );
133 return <Collapse isOpen={isOpen} render={render} />;
134};
135```
136
137There are four possible collapse states: `collapsed`, `collapsing`, `expanded`, `expanding`.
138
139#### `className` : string
140
141You can specify a custom className. The default value is `collapse-css-transition`. Remember to add CSS transition if a className is provided.
142
143#### `transition` : string
144
145You can also specify a CSS transition inline by using the `transition` prop.
146
147```jsx
148const MyComponent = ({ isOpen, duration = "290ms" }) => (
149 <Collapse
150 transition={`height ${duration} cubic-bezier(.4, 0, .2, 1)`}
151 isOpen={isOpen}
152 >
153 <p>Paragraph of text</p>
154 </Collapse>
155);
156```
157
158#### `elementType` : string
159
160You can specify the HTML element type for the collapse component. By default the element type is a `div` element.
161
162```jsx
163const MyComponent = ({ isOpen }) => (
164 <Collapse elementType="article" isOpen={isOpen}>
165 <p>Paragraph of text inside an article element</p>
166 </Collapse>
167);
168```
169
170#### `collapseHeight` : string
171
172You can specify the collapse height in CSS unit to partially show some content.
173
174```jsx
175const MyComponent = ({ isOpen }) => (
176 <Collapse collapseHeight="40px" isOpen={isOpen}>
177 <p>A long paragraph of text inside an article element</p>
178 </Collapse>
179);
180```
181
182#### `onChange` : function
183
184Callback function for when the transition changes.
185
186```jsx
187const MyComponent = ({ isOpen }) => {
188 const onChange = ({ state, style }) => {
189 /*
190 state: string = the state of the collapse component.
191 style: object = styles that are applied to the component.
192 */
193 };
194
195 return (
196 <Collapse onChange={onChange} isOpen={isOpen}>
197 <p>A long paragraph of text inside an article element</p>
198 </Collapse>
199 );
200};
201```
202
203#### `onInit` : function
204
205Similar to onChange but only invoked on DOM mounted.<br/>
206This is an example that starts collapsed and expands on mount.
207
208```jsx
209const MyComponent = () => {
210
211 const [isOpen, setIsOpen] = React.useState(false);
212
213 const onInit = ({ state, style, node }) => {
214 /*
215 node: HTMLElement = the DOM node of the component.
216 */
217
218 setIsOpen(true);
219 };
220
221 return (
222 <div>
223 <button onClick={() => setIsOpen(state => !state)}> Toggle </button>
224 <Collapse onInit={onInit} isOpen={isOpen}>
225 <p>A long paragraph of text inside an article element</p>
226 </Collapse>
227 </div>
228 );
229};
230```
231
232#### `addState` : boolean
233
234If added, then one of the class names will be appended to the component depending on the state.
235
236```
237--c-collapsed
238--c-collapsing
239--c-expanded
240--c-expanding
241```
242
243#### `noAnim` : boolean
244
245If added, then there will be no collapse animation. State changes between `collapsed` and `expanded`.
246
247#### `overflowOnExpanded` : boolean
248
249If added, then `overflow: hidden` style will not be added when the state is `expanded`.
250
251#### Custom props
252
253`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:
254
255```jsx
256const MyComponent = ({ isOpen }) => (
257 <Collapse aria-hidden={isOpen ? "false" : "true"} isOpen={isOpen}>
258 <p>Paragraph of text</p>
259 </Collapse>
260);
261```
262
263Or you could specify a specific transitionDuration.
264
265```jsx
266const collapseStyles = { transitionDuration: "270ms" };
267
268const MyComponent = ({ isOpen }) => (
269 <Collapse style={collapseStyles} isOpen={isOpen}>
270 <p>Paragraph of text</p>
271 </Collapse>
272);
273```
274
275## Development and testing
276
277To run development
278
279`npm start` or `yarn start`
280
281```bash
282git clone [repo]
283cd [repo]
284npm i
285npm start
286open http://localhost:6007
287npm test
288```
289
290or with **yarn**
291
292```bash
293git clone [repo]
294cd [repo]
295yarn
296yarn start
297open http://localhost:6007
298yarn test
299```
300
301- To develop and play around: `yarn start`
302- To build the bundle: `yarn build`
303- To validate the bundle: `yarn validate`
304
305To run example covering all features, use `npm run storybook` or `yarn storybook`.
306
307# CDN
308
309https://unpkg.com/@kunukn/react-collapse/
310
311```html
312<link
313 rel="stylesheet"
314 href="https://unpkg.com/@kunukn/react-collapse/dist/Collapse.umd.css"
315/>
316<script src="https://unpkg.com/@kunukn/react-collapse/dist/Collapse.umd.js"></script>
317
318<script>
319 var Collapse = window.Collapse;
320</script>
321```
322
323# Supported browsers
324
325IE11 + Modern browsers
326
327# Supported React versions
328
329- React version 16.3+ : use Collapse version 1
330- React version 16.8+ : use Collapse version 2+
331
332# Used React 16.3 life-cycles
333
334- **render** (uses the style states to invoke CSS transition)
335- **componentDidMount** (initial expanded or collapsed state)
336- **getDerivedStateFromProps** (detect if isOpen props has changed and apply a new collapse state)
337- **componentDidUpdate** (update style states from the four possible collapse states)
338
339# Used React 16.8 hooks
340
341- **useState**
342- **useEffect**
343- **useRef**
344- **useCallback**
345- **useReducer**
346
347# Design goals
348
349- let the browser handle the animation using CSS height transition
350- minimal in file size
351- minimalistic API - only have a Collapse component which updates on isOpen props
352- flexible - provide your own markup, styling and easing
353- interruptible - can be reversed during movement
354- inert - when collapsed you should tab over the collapsed component
355- availability - from cdn or npm install
356- Collapsible on height only
357
358# This was created with heavy inspiration from
359
360[https://github.com/SparebankenVest/react-css-collapse](https://github.com/SparebankenVest/react-css-collapse) 🎆