Reputation: 582
I have a Table and I have Collapse component in each row. I want to add chevron to it and when I clicked it I want content to be appeared and chevron changes its shape. How can I do that in table ?
Ps: Is it possible to do that without defining state?
Here is an example
https://stackblitz.com/edit/reactstrap-uncontrolled-collapse-2qgsf6?file=index.js,index.html
Upvotes: 1
Views: 367
Reputation: 48630
You need to use a controlled Collapse
instead of an UncontrolledCollapse
.
Also, your data should be in an array, and be mapped inside the render()
function.
Finally, I would also avoid using a clunky <table>
element to structure your content. Go with a FlexBox or Gird layout.
Note: If this.state.toggleStates[index]
is true
, this means that the .AccordianItem
is expanded.
import React, { Component } from 'react';
import { render } from 'react-dom';
import { Card, CardBody, Collapse } from 'reactstrap';
import './style.css';
const rows = [
{
title: 'Request Headers:',
body: `Lorem ipsum dolor sit amet consectetur adipisicing elit.
Nesciunt magni, voluptas debitis similique porro a
molestias consequuntur earum odio officiis natus, amet
hic, iste sed dignissimos esse fuga! Minus, alias.`,
},
{
title: 'Request Headers:',
body: `Lorem ipsum dolor sit amet consectetur adipisicing elit.
Nesciunt magni, voluptas debitis similique porro a
molestias consequuntur earum odio officiis natus, amet
hic, iste sed dignissimos esse fuga! Minus, alias.`,
},
];
class App extends Component {
constructor() {
super();
this.state = {
name: 'React',
toggleStates: Array.from(rows, () => false),
};
}
toggleIndex(index) {
const toggleStates = [...this.state.toggleStates];
toggleStates[index] = !toggleStates[index]; // toggle the state
this.setState({ toggleStates });
}
render() {
return (
<div className="App">
<div className="Accordion">
{rows.map(({ title, body }, index) => (
<div className="AccordionItem">
<div
className="AccordionItemHeader"
onClick={() => this.toggleIndex(index)}
>
<box-icon
name={
this.state.toggleStates[index]
? 'chevron-down'
: 'chevron-right'
}
></box-icon>
<b>{title}</b>
</div>
<div className="AccordionItemContent">
<Collapse isOpen={this.state.toggleStates[index]}>
<Card>
<CardBody>{body}</CardBody>
</Card>
</Collapse>
</div>
</div>
))}
</div>
</div>
);
}
}
render(<App />, document.getElementById('root'));
html,
body,
#root {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#root {
display: flex;
align-items: flex-start;
justify-content: center;
padding: 1rem;
}
.App {
display: flex;
flex-direction: column;
width: 400px;
}
.Accordion {
display: flex;
flex-direction: column;
}
.AccordionItem {
display: flex;
flex-direction: column;
}
.AccordionItemHeader {
display: grid;
grid-template-columns: auto 1fr;
align-items: center;
justify-content: center;
padding: 0.5rem;
background: #ddd;
}
.AccordionItemContent {
flex: 1;
}
Here is the modified StackBlitz:
https://stackblitz.com/edit/reactstrap-uncontrolled-collapse-pzq9af?file=style.css
Upvotes: 2