Skip to content
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): Use empty SelectableContext to prevent dropdown from closing accordion #5201

Merged
merged 1 commit into from
Aug 12, 2020

Conversation

kyletsang
Copy link
Member

Fixes #4176

I moved the SelectableContext consumption to NavDropdown because it looks like this context is used in conjunction with Nav in triggering onSelect for NavDropdowns.

I've added the test in Nav to make sure I didn't break anything in that API and another test in Accordion to make sure the a dropdown would not trigger the accordion context.

This would also close the PR #4772.

Copy link
Member

@taion taion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @jquense does this API change make sense to you?

});

return (
<Dropdown ref={ref} onSelect={handleSelect} {...props} as={NavItem}>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wonder if we want to make as customizable in this context, then.

with this change, rendering a <Dropdown> with whatever styling inside a <Nav> now won't do the same thing as rendering a <NavDropdown>

which is probably okay, but maybe a bit more customizability here would help

@kyletsang
Copy link
Member Author

@taion, I just revisited this and I realized anything that implements AbstractNav would suffer the same issue of collapsing the accordion inadvertently. I'm thinking a better solution would be to wrap everything in AccordionCollapse with <SelectableContext.Provider value={null}>?

ie. in AccordionCollapse.js

return (
  <SelectableContext.Provider value={null}>
    <Collapse ref={ref} in={contextEventKey === eventKey} {...props}>
      <div>{React.Children.only(children)}</div>
    </Collapse>
  </SelectableContext.Provider>
);

What do you think?

@taion
Copy link
Member

taion commented Jun 22, 2020

That could work. We might want to do that in general wherever we consume this context, then?

Could also use a different context here, but I guess that'd be breaking.

I'm not sure. Is it definitely the case that AbstractNav shouldn't call into the parent onSelect from an accordion parent?

@kyletsang
Copy link
Member Author

TBH, I can't think of any case where elements within the collapse would want to trigger the accordion parent.

@taion
Copy link
Member

taion commented Jun 22, 2020

well, it's sort of like nested navigation... idk

we can try that out, though

@kyletsang
Copy link
Member Author

I'll update the PR anyway since the original solution doesn't cover all cases. Others can chime in and we can close this if it's no good.

@jquense @bpas247 @mxschmitt

@eshwar-quartic
Copy link

@taion Any ETA on getting this merged?

@jquense
Copy link
Member

jquense commented Jul 31, 2020

I'm a bit concerned this change will break anyone using a custom dropdown in a navbar. I think maybe the underlying issue is we are reusing SelectableContext when we should probably have a different SelectableContext "instances" for each, lack of a better word, group of selectable behaviors. Then the contexts would talk past each other but maintain a unified public interface.

something like:

NavSelectableContext = createSelectableContext();
AccordianSelectableContext = createSelectableContext()

@taion
Copy link
Member

taion commented Jul 31, 2020

Oh, that sounds reasonable to me. Can we make that change for v1, though, or does it need to be deferred for v2?

@jquense
Copy link
Member

jquense commented Jul 31, 2020

I think this can go into a v1, it is maintaining the same API, and fixes a bug...is the SelectionContext public?

@taion
Copy link
Member

taion commented Jul 31, 2020

It's not explicitly documented nor exposed at top-level. I think we may have pointed people toward it for cases where they need more fine-grained control, though.

@kyletsang
Copy link
Member Author

Oops I forgot to update the title here - it no longer reflects the new change.

What I ended up doing is wrapping the AccordionCollapse with a null SelectableContext. This prevents the elements inside the collapse from grabbing the context.

Looking at the code I believe the only element that uses SelectableContext is the toggle. I don't think the contents of the collapse need the root SelectableContext from Accordion.... does it?

@jquense

@kyletsang kyletsang changed the title fix(Dropdown): Move SelectableContext consumption to NavDropdown fix(Dropdown): Wrap AccordionCollapse with empty SelectableContext Jul 31, 2020
@kyletsang kyletsang changed the title fix(Dropdown): Wrap AccordionCollapse with empty SelectableContext fix(Dropdown): Use empty SelectableContext to wrap Collapse in AccordionCollapse Jul 31, 2020
@kyletsang kyletsang changed the title fix(Dropdown): Use empty SelectableContext to wrap Collapse in AccordionCollapse fix(Accordion): Use empty SelectableContext to prevent dropdown from closing accordion Aug 11, 2020
@kyletsang kyletsang requested a review from jquense August 11, 2020 06:11
@tmm1
Copy link

tmm1 commented Sep 12, 2020

Thanks for this fix! Any chance of a 1.3.1 release soon with this included?

@tmm1
Copy link

tmm1 commented Dec 4, 2020

@taion friendly ping for a new release sometime :)

@kyletsang
Copy link
Member Author

@tmm1 this is available in 1.4.0

@tmm1
Copy link

tmm1 commented Dec 4, 2020

Thanks! I missed that on https://github.com/react-bootstrap/react-bootstrap/releases

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

onClick stopPropagation() ignored on Dropdown, DropdownButton
5 participants