-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(Accordion) fix wrong indexes when using Accordion.Title and Accordion.Content #832
fix(Accordion) fix wrong indexes when using Accordion.Title and Accordion.Content #832
Conversation
Current coverage is 100% (diff: 100%)
|
const isTitle = child.type === AccordionTitle | ||
const isContent = child.type === AccordionContent | ||
|
||
if (isTitle) { | ||
const isActive = _.has(child, 'props.active') ? child.props.active : activeIndex === i | ||
const currentIndex = titleIndex |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we remove currentIndex
from this block and the isContent block and just use titleIndex
and contentIndex
respectively? I think it is a little more clear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did that at first
if (isTitle) {
const isActive = _.has(child, 'props.active') ? child.props.active : activeIndex === titleIndex
const onClick = (e) => {
this.handleTitleClick(e, titleIndex)
if (child.props.onClick) child.props.onClick(e, titleIndex)
}
titleIndex++
return cloneElement(child, { ...child.props, active: isActive, onClick })
}
if (isContent) {
const isActive = _.has(child, 'props.active') ? child.props.active : activeIndex === contentIndex
contentIndex++
return cloneElement(child, { ...child.props, active: isActive })
}
But if you do this, than all titles will have index 3 in the callback. Like the lambda gets not only lazy evaluation, but lazy creation, or value is passed by reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, indeed. It is a reference and there is a single titleIndex
available. Good catch.
@@ -77,6 +77,29 @@ describe('Accordion', () => { | |||
wrapper | |||
.should.have.state('activeIndex', -1) | |||
}) | |||
it('is called with (event, index) on AccordionTitle click', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this test. Could we also add one more test similar to this that asserts that the correct title/content are "active" given an activeIndex
of 0, 1, and 2? Something like this added to describe('activeIndex')
, note I did not test this so it could have issues:
it('sets the correct pair of title/content active', () => {
const wrapper = shallow(
<Accordion>
<Accordion.Title />
<Accordion.Content />
<Accordion.Title />
<Accordion.Content />
<Accordion.Title />
<Accordion.Content />
</Accordion>
)
wrapper.setProps({ activeIndex: 0 })
wrapper.childAt(0).should.have.prop('active', true)
wrapper.childAt(1).should.have.prop('active', true)
wrapper.setProps({ activeIndex: 1 })
wrapper.childAt(2).should.have.prop('active', true)
wrapper.childAt(3).should.have.prop('active', true)
wrapper.setProps({ activeIndex: 2 })
wrapper.childAt(4).should.have.prop('active', true)
wrapper.childAt(5).should.have.prop('active', true)
})
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course, sure I can add this
Released in |
RFC
fixes #773
I fix wrong indexes but I find the code kinda ugly. It would be better if we don't need to copy index into local variable, but without it its buggy, i'm not sure why.
Another way: still use
child.index
but divide it by two like thisBut its hard to read