EN
Create simple animated expander in React
6 points
Hi there! π π
Today, I was thinking about creating an animated expander in React and I came up with the following solution.
Effect of this short post:

In the example below, I create a simple expander that displays Fruits π and Vegetables π
lists on click event. I've used a modern approach that involves the use of functional components and React hooks. In this case useState
hook stores the state of my expander. πΊπ»
Runnable example:
xxxxxxxxxx
1
//Note: Uncomment import lines during working with JSX Compiler.
2
// import React from 'react';
3
// import ReactDOM from 'react-dom';
4
β
5
const expanderStyle = {
6
margin: '6px 0',
7
padding: '2px',
8
border: '1px solid #85C1E9'
9
};
10
β
11
const headerStyle = {
12
display: 'flex',
13
cursor: 'pointer'
14
};
15
β
16
const titleStyle = {
17
padding: '3px',
18
flex: 'none'
19
};
20
β
21
const spacerStyle = {
22
flex: '1'
23
};
24
β
25
const iconStyle = {
26
padding: '3px',
27
flex: 'none'
28
};
29
β
30
const contentStyle = {
31
overflow: 'hidden',
32
transition: 'all 0.3s'
33
};
34
β
35
const contentExpandedStyle = {
36
contentStyle,
37
padding: '4px 0',
38
border: '1px solid #85C1E9',
39
height: 'auto',
40
filter: 'opacity(1)'
41
};
42
β
43
const contentCollapsedStyle = {
44
contentStyle,
45
padding: '0 0',
46
border: '1px solid transparent',
47
height: '0',
48
filter: 'opacity(0)'
49
};
50
β
51
const Expander = ({title, children}) => {
52
const [expanded, setExpanded] = React.useState(false);
53
const handleHeaderClick = () => {
54
setExpanded(expanded => !expanded);
55
};
56
return (
57
<div style={expanderStyle}>
58
<div style={headerStyle} onClick={handleHeaderClick}>
59
<div style={titleStyle}>{title}</div>
60
<div style={spacerStyle} />
61
<div style={iconStyle}>{expanded ? 'πΊ' : 'π»'}</div>
62
</div>
63
<div style={expanded ? contentExpandedStyle : contentCollapsedStyle}>
64
{children}
65
</div>
66
</div>
67
);
68
};
69
β
70
// Usage example:
71
β
72
const App = () => {
73
return (
74
<div style={{height: '260px'}}>
75
<Expander title="πππ Fruits">
76
<ul>
77
<li>π Apple</li>
78
<li>π Banana</li>
79
<li>π Orange</li>
80
</ul>
81
</Expander>
82
<Expander title="π₯π₯π
Vegetables">
83
<ul>
84
<li>π₯ Carrot</li>
85
<li>π₯ Cucumber</li>
86
<li>π
Tomato</li>
87
</ul>
88
</Expander>
89
</div >
90
);
91
};
92
β
93
const root = document.querySelector('#root');
94
ReactDOM.render(<App/>, root );