jforaker / react-accordion-with-header

React accordion component with flexbox header
https://react-accordion.xyz
16 stars 18 forks source link

Add new prop - isOpen #5

Closed KRav007 closed 6 years ago

KRav007 commented 6 years ago

I came across this module and it works very well. The only prop is missing, is, "isOpen". With this new prop you can open a certain panel on init.

jforaker commented 6 years ago

Very cool @KRav007 !! Love the idea.

One issue I ran in to while testing... if I set firstOpen: false and isOpen: 0 what should be the expected result?

    this.state = {
      multipleOkay: false,
      firstOpen: false,
      isOpen: 0
    };

For me, isOpen overrides firstOpen: false, meaning if you set firstOpen: false and isOpen: 0, the first panel will be open. I think this is ok, just wondering if you thought about it or had any more ideas.

Just want to hear your thoughts before I merge it.

Good stuff.

KRav007 commented 6 years ago

Hey Jake,

You are right, this is the expected result. I wanted to keep it simple, yes , "isOpen" overrides "firstOpen.

Cheers Kai

jforaker commented 6 years ago

Cool. Now I'm wondering if firstOpen is even useful. Perhaps isOpen could turn into something more flexible, for ex maybe it accepts a bunch of options:

"first", "last", 0, undefined, [0,2,3], ["first", "last"], "all"  etc...

Might have to change the name in that because of singular versus plural. Just riffing as I think about stuff here..

KRav007 commented 6 years ago

"I'm wondering if firstOpen is even useful" - right. The option Idea is good, but I would not give to much options. Keep it simple: [], [0,2,3,x], ["first", "last", "all"],

jforaker commented 6 years ago

Thanks @KRav007 for the feedback. This idea inspired me to refactor the component to allow for external control.

Instead of isOpen, you can pass in an array to active and control the Accordion externally.

For example lets say you had a button that called the toggleActive method below:


  state = {
    active: [0]
  };

  toggleActive = () => {
    this.setState({
      active: Array.from({ length: Math.round(Math.random() * 3) }).map(
        (_, i) => i
      )
    });
  };

      <AccordionWithHeader active={this.state.active}>
        {[1, 2, 3, 4].map((item, i) => {
          return (
            <AccordionNode key={i}>
              <AccordionHeader>
                <div>This is the header</div>
              </AccordionHeader>
              <AccordionPanel>
                <div>This is the body</div>
              </AccordionPanel>
            </AccordionNode>
          );
        })}
      </AccordionWithHeader>

The only trade off is you have to manually control the panels in this case. See the example in the demos.