or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

css-transition.mdindex.mdreplace-transition.mdswitch-transition.mdtransition-group.mdtransition.md

transition-group.mddocs/

0

# Transition Groups

1

2

The TransitionGroup component manages a set of transition components in a list, automatically coordinating the mounting and unmounting of items with proper transition timing.

3

4

## Capabilities

5

6

### TransitionGroup Component

7

8

Manages transitions for dynamic lists of components, handling enter and exit animations for list items.

9

10

```javascript { .api }

11

/**

12

* Manages a set of transition components in a list with automatic coordination

13

* @param props - TransitionGroup props

14

* @returns JSX element containing managed transition children

15

*/

16

function TransitionGroup({

17

component,

18

children,

19

appear,

20

enter,

21

exit,

22

childFactory,

23

...otherProps

24

}): JSX.Element;

25

26

interface TransitionGroupProps {

27

/** Component to render as container (default: 'div', use null for no wrapper) */

28

component?: React.ComponentType<any> | string | null;

29

/** Set of Transition or CSSTransition components to manage */

30

children?: React.ReactNode;

31

/** Enable/disable appear animations for all children */

32

appear?: boolean;

33

/** Enable/disable enter animations for all children */

34

enter?: boolean;

35

/** Enable/disable exit animations for all children */

36

exit?: boolean;

37

/** Function to wrap every child, including exiting ones */

38

childFactory?: (child: React.ReactElement) => React.ReactElement;

39

}

40

```

41

42

**Usage Examples:**

43

44

```javascript

45

import React, { useState } from 'react';

46

import { TransitionGroup, CSSTransition } from 'react-transition-group';

47

import './list.css';

48

49

function TodoList() {

50

const [items, setItems] = useState([

51

{ id: 1, text: 'Buy milk' },

52

{ id: 2, text: 'Walk dog' },

53

{ id: 3, text: 'Write code' }

54

]);

55

56

const addItem = () => {

57

const newItem = {

58

id: Date.now(),

59

text: `Item ${items.length + 1}`

60

};

61

setItems([...items, newItem]);

62

};

63

64

const removeItem = (id) => {

65

setItems(items.filter(item => item.id !== id));

66

};

67

68

return (

69

<div>

70

<TransitionGroup component="ul" className="todo-list">

71

{items.map(item => (

72

<CSSTransition

73

key={item.id}

74

timeout={300}

75

classNames="item"

76

>

77

<li onClick={() => removeItem(item.id)}>

78

{item.text}

79

</li>

80

</CSSTransition>

81

))}

82

</TransitionGroup>

83

<button onClick={addItem}>Add Item</button>

84

</div>

85

);

86

}

87

88

// Without wrapper element

89

function NoWrapperGroup({ items }) {

90

return (

91

<TransitionGroup component={null}>

92

{items.map(item => (

93

<CSSTransition

94

key={item.id}

95

timeout={200}

96

classNames="fade"

97

>

98

<div className="item">{item.text}</div>

99

</CSSTransition>

100

))}

101

</TransitionGroup>

102

);

103

}

104

```

105

106

### Child Factory Function

107

108

The `childFactory` prop allows modification of children, including those that are exiting:

109

110

```javascript { .api }

111

/**

112

* Child factory function for modifying transition children

113

* @param child - React element being managed by TransitionGroup

114

* @returns Modified React element

115

*/

116

type ChildFactory = (child: React.ReactElement) => React.ReactElement;

117

```

118

119

**Usage Example:**

120

121

```javascript

122

function DynamicTransitionGroup({ items, fastExit }) {

123

const childFactory = (child) => {

124

// Modify exiting children to use faster animation

125

return React.cloneElement(child, {

126

timeout: fastExit ? 100 : 300,

127

classNames: fastExit ? 'fast-exit' : 'normal'

128

});

129

};

130

131

return (

132

<TransitionGroup childFactory={childFactory}>

133

{items.map(item => (

134

<CSSTransition

135

key={item.id}

136

timeout={300}

137

classNames="normal"

138

>

139

<div>{item.text}</div>

140

</CSSTransition>

141

))}

142

</TransitionGroup>

143

);

144

}

145

```

146

147

### List Animation Patterns

148

149

Common patterns for animating lists with TransitionGroup:

150

151

**Staggered Animations:**

152

```javascript

153

function StaggeredList({ items }) {

154

return (

155

<TransitionGroup component="div" className="staggered-list">

156

{items.map((item, index) => (

157

<CSSTransition

158

key={item.id}

159

timeout={300}

160

classNames="stagger"

161

style={{ animationDelay: `${index * 50}ms` }}

162

>

163

<div className="list-item">

164

{item.text}

165

</div>

166

</CSSTransition>

167

))}

168

</TransitionGroup>

169

);

170

}

171

```

172

173

**Complex List Operations:**

174

```javascript

175

function AdvancedList() {

176

const [items, setItems] = useState([]);

177

178

const handleReorder = (fromIndex, toIndex) => {

179

const newItems = [...items];

180

const [removed] = newItems.splice(fromIndex, 1);

181

newItems.splice(toIndex, 0, removed);

182

setItems(newItems);

183

};

184

185

return (

186

<TransitionGroup component="div">

187

{items.map(item => (

188

<CSSTransition

189

key={item.id}

190

timeout={{ enter: 300, exit: 200 }}

191

classNames="list-item"

192

>

193

<div

194

className="draggable-item"

195

onDragEnd={(e) => handleReorder(...)}

196

>

197

{item.text}

198

</div>

199

</CSSTransition>

200

))}

201

</TransitionGroup>

202

);

203

}

204

```

205

206

### TransitionGroup Behavior

207

208

TransitionGroup automatically:

209

210

1. **Tracks children by key**: Uses React keys to identify which items are entering, staying, or leaving

211

2. **Manages transition props**: Automatically sets `in` prop to `true` for entering items and `false` for exiting items

212

3. **Handles exit cleanup**: Removes components from DOM after exit transition completes

213

4. **Coordinates timing**: Ensures proper sequencing of enter/exit animations

214

215

### Key Requirements

216

217

All children of TransitionGroup must have unique `key` props:

218

219

```javascript

220

// ✅ Correct - each child has unique key

221

<TransitionGroup>

222

{items.map(item => (

223

<CSSTransition key={item.id} timeout={200} classNames="fade">

224

<div>{item.text}</div>

225

</CSSTransition>

226

))}

227

</TransitionGroup>

228

229

// ❌ Incorrect - missing or duplicate keys will cause issues

230

<TransitionGroup>

231

{items.map(item => (

232

<CSSTransition timeout={200} classNames="fade">

233

<div>{item.text}</div>

234

</CSSTransition>

235

))}

236

</TransitionGroup>

237

```

238

239

### Example CSS for List Animations

240

241

```css

242

/* Slide in from right, slide out to left */

243

.item-enter {

244

transform: translateX(100%);

245

opacity: 0;

246

}

247

248

.item-enter-active {

249

transform: translateX(0);

250

opacity: 1;

251

transition: all 300ms ease-out;

252

}

253

254

.item-exit {

255

transform: translateX(0);

256

opacity: 1;

257

}

258

259

.item-exit-active {

260

transform: translateX(-100%);

261

opacity: 0;

262

transition: all 200ms ease-in;

263

}

264

265

/* Scale and fade */

266

.scale-enter {

267

transform: scale(0.8);

268

opacity: 0;

269

}

270

271

.scale-enter-active {

272

transform: scale(1);

273

opacity: 1;

274

transition: all 250ms cubic-bezier(0.175, 0.885, 0.32, 1.275);

275

}

276

277

.scale-exit {

278

transform: scale(1);

279

opacity: 1;

280

}

281

282

.scale-exit-active {

283

transform: scale(0.8);

284

opacity: 0;

285

transition: all 150ms ease-in;

286

}

287

```