react-accordion-with-header
Version:
React accordion component with flexbox header
156 lines (119 loc) • 7.7 kB
Markdown
# react-accordion-with-header
### React accordion component with customizable flexbox header
[](https://nodei.co/npm/react-accordion-with-header?downloads=true)
> "You've got 5 seconds... and 3 are up." - _Steven Seagal_
<img src="https://media.giphy.com/media/BakXonJxQzoIM/giphy.gif" width="300" />
### [Check out the demo NOW](https://react-accordion-with-header.now.sh/)
#### Install via NPM:
```
npm install react-accordion-with-header
```
#### Import the modules:
```javascript
import {
AccordionWithHeader,
AccordionNode,
AccordionHeader,
AccordionPanel
} from 'react-accordion-with-header';
```
Items can be passed in to `<AccordionHeader />` and `<AccordionPanel />`:
- as children (preferred)
- as a component passed into the `template` prop (deprecated)
The elements passed in to `<AccordionHeader />` can be **horizontally justified and vertically aligned** via their respective props
:tada: :boom: :beers:
- `horizontalAlignment`
- `verticalAlignment`
### Pass in a component as a child to `AccordionHeader` and `AccordionPanel`:
(or plain html of course)
```javascript
// note: due to the warning "Stateless function components cannot be given refs. Attempts to access this ref will fail."
// the components passed into <AccordionPanel> must be class components
// this allows to measure the height of the element via refs
class BodyTpl extends React.Component {
render() {
return <div>Look at this {this.props.item}</div>;
}
}
class MyAccordion extends React.Component {
render() {
return (
<AccordionWithHeader>
{[1, 2, 3, 4].map((item, i) => {
return (
<AccordionNode key={i}>
<AccordionHeader
horizontalAlignment="centerSpaceAround"
verticalAlignment="center"
>
<div>This is the header</div>
<div>It has flexbox layout</div>
</AccordionHeader>
<AccordionPanel>
<BodyTpl item={item} />
</AccordionPanel>
</AccordionNode>
);
})}
</AccordionWithHeader>
);
}
}
…
```
### `actionCallback`
```javascript
…
actionCallback = (panels, state) => {
// fires any time headers are clicked and panels change state
// receives array of panels: [{ panel: 3, open: true }, { panel: 6, open: true }]
// and the AccordionWithHeader state
console.log('panels, state', panels, state);
}
render() {
return (
<AccordionWithHeader actionCallback={this.actionCallback}>
// ... stuff
</AccordionWithHeader>
);
}
…
```
## Props
(all components accept a `className` and `style` prop per usual convention)
### `<AccordionWithHeader />`
| Property | Type | Description | Default |
| :------------- | :--------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- | :------ |
| firstOpen | `Boolean` | Determines if the first panel should be expanded on init | `false` |
| active | `Array` | Determines which panels are open (on componentDidMount or to control externally) | `[]` |
| multipleOkay | `Boolean` | True allows multiple panels to be expanded at the same time. False allows only one panel to be expanded at any time. | `false` |
| actionCallback | `Function` | Callback function fired when a header is clicked and panel is opened or closed. Returns an array representing panels and the AccordionWithHeader state | `none` |
| style | `Object` | style object | `none` |
| className | `String` | CSS classname | `none` |
### `<AccordionNode />`
| Property | Type | Description | Default |
| :-------- | :------- | :---------------------------------------- | :------ |
| style | `Object` | style object | `none` |
| className | `String` | Custom classname applied to root item div | `none` |
### `<AccordionHeader />`
| Property | Type | Description | Default |
| :------------------ | :-------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------ |
| title | `String` | For simple headers, a title will render an `<h1>` and disallow child elements | `none` |
| titleColor | `String` | some valid CSS color or rgb or hex | `black` |
| horizontalAlignment | `String` | One of: 'centerSpaceBetween', 'spaceBetween', 'centerSpaceAround', 'spaceAround', 'spaceEvenly', 'center', 'left', 'right'. Maps to corresponding flex-box CSS property | `centerSpaceAround` |
| verticalAlignment | `String` | One of: 'top', 'center', 'bottom' | `center` |
| style | `Object` | style object | `none` |
| className | `String` | CSS classname | `none` |
| template | `Element` | Component to be rendered as a template | `none` |
### `<AccordionPanel />`
| Property | Type | Description | Default |
| :-------- | :-------- | :-------------------------------------------------------------------- | :------ |
| template | `Element` | Component to be rendered as a template | `none` |
| speed | `Number` | Speed in milliseconds to apply to CSS transition of open/close effect | `250` |
| style | `Object` | style object | `none` |
| className | `String` | CSS classname | `none` |
## What about styling?
You can styles to any component with a `style` prop or `className` prop
For example: `<AccordionHeader style={{border: '1px solid'}}>`
Or: `<AccordionHeader className="myCssClass">`
---