Я использую эту библиотеку https://github.com/emilpalsson/react-tiny-accordion, чтобы добавить простой аккордеон в мой реактивный проект.Однако, если я изменю поле формы или нажму кнопку в разделе аккордеона, он также закроет весь раздел, когда я на самом деле хочу оставаться открытым, пока я заполняю этот раздел формы.
Я решил, что кнопкаФункция onClick запускала аккордеон onClick, и я пытался сделать e.stopPropagation()
в моих функциях onClick кнопки, но это не имело никакого значения.Я еще не очень хорошо знаю, как реагировать, и код из библиотеки мне немного сложен для понимания (особенно потому, что он использует ссылки, а я их раньше не использовал).Был бы признателен, если бы кто-то мог дать некоторое представление о том, что мне, возможно, нужно изменить или добавить?
Код, используемый для настройки аккордеона:
import React from 'react'
class Accordion extends React.Component {
constructor(props) {
super(props)
const { children, selectedIndex } = this.props
this.index = typeof props.selectedIndex !== 'undefined' ? props.selectedIndex : -1
this.nodes = []
this.state = {
heights: React.Children.map(
children,
(child, index) => (index === selectedIndex ? 'auto' : 0)
)
}
}
componentWillReceiveProps(props) {
const { selectedIndex } = props
if (typeof selectedIndex !== 'undefined' && this.index !== selectedIndex) {
this.toggle(selectedIndex)
}
}
componentWillUnmount() {
clearTimeout(this.timeout)
}
close(index) {
setTimeout(() => this.setHeight(index, 0), 50)
}
setHeight(index, height, callback) {
const heights = this.state.heights.slice()
heights[index] = height
this.setState({ heights }, callback)
}
open(index) {
clearTimeout(this.timeout)
this.setHeight(index, this.nodes[index].children[1].children[0].offsetHeight, () => {
this.timeout = setTimeout(() => this.setHeight(index, 'auto'), this.props.transitionDuration)
})
}
setFixedHeightOnCurrentlyOpenedItem() {
return new Promise(resolve => {
if (this.index > -1) {
this.setHeight(
this.index,
this.nodes[this.index].children[1].children[0].offsetHeight,
resolve
)
}
else {
resolve()
}
})
}
toggle(index, click) {
const { onChange, changeOnClick } = this.props
clearTimeout(this.timeout)
if (click) {
if (onChange) {
onChange(index, this.index !== index, this.index !== index ? index : -1)
}
if (!changeOnClick) return
}
// First, set a fixed height on the currently opened item, for collapse animation to work
this.setFixedHeightOnCurrentlyOpenedItem().then(() => {
if (this.index > -1) {
this.close(this.index)
}
if (index > -1 && index !== this.index) {
this.index = index
this.open(index)
}
else {
this.index = -1
}
})
}
render() {
const { transitionDuration, transitionTimingFunction, className, openClassName } = this.props
const nodes = React.Children.map(this.props.children, (child, index) => (
<div
key={index}
ref={div => {
this.nodes[index] = div
}}
className={this.index === index ? openClassName : ''}
>
<div onClick={() => this.toggle(index, true)}>{child.props['data-header']}</div>
<div style={{
overflow: 'hidden',
transition: `height ${transitionDuration}ms ${transitionTimingFunction}`,
height: this.state.heights[index]
}}>{child}</div>
</div>
))
return <div className={className}>{nodes}</div>
}
}
Accordion.defaultProps = {
transitionDuration: 500,
transitionTimingFunction: 'ease',
openClassName: 'open',
changeOnClick: true
}
export default Accordion
Код моей формы - нажата кнопкаили поле формы, введенное в один из компонентов FormSection, приведет к закрытию аккордеона.
class Form extends Component{
state = { selectedIndex: 0}
render(){
const {
handleFormChange,
buttonClick,
handleFormData
} = this.props;
return (
<React.Fragment>
<h1>Form</h1>
<form id="form" onChange={handleFormChange}>
<Accordion className="accordion" selectedIndex={this.state.selectedIndex}>
<div className="accordion-item" data-header="Step 1">
<FormSection1 buttonClick={buttonClick}/>
</div>
<div className="accordion-item" data-header="Step 2">
<FormSection2 />
</div>
<div className="accordion-item" data-header="Step 3">
<FormSection3 handleFormData={handleFormData} />
</div>
</Accordion>
</form>
</React.Fragment>
)
}
}
По сути, все, что я хочу, это чтобы секция аккордеона оставалась открытой, пока я заполняю форму и нажимаю любые кнопки вэтот раздел.Оно должно закрываться, только если я щелкну строку заголовка или следующий раздел формы.