nkbt / react-collapse

Component-wrapper for collapse animation with react-motion for elements with variable (and dynamic) height
MIT License
1.12k stars 113 forks source link

Make collapse content initially open #242

Closed isaacalves closed 4 years ago

isaacalves commented 5 years ago

Is it possible to have the component opened by default without animating on page load?

I know this actually works, here: https://codepen.io/isaacalves/pen/zmvLNV

But the only way to achieve that in my build is to have the height of the content set in the CSS, but that won't work because the content is dynamic.

I have the exact same thing (really, the exact same thing, I copied and pasted it, no CSS nothing) as in the Codepen link above in my build but it doesn't work, it's always closed by default.

The react-collapse and react-motion version of my build are the same as in the Codepen above.

    "react-collapse": "4.0.3",
    "react-motion": "0.5.2",

I honestly don't know what else I could do. Any ideas?

I realised that the ReactCollapse--collapse element starts with height 0 (it's set somewhere with JS, not CSS) while in the Codepen sample above that doesn't happen, height is unset. How come that happens?

nkbt commented 5 years ago

Not really it works with any content height since when collapse is in "stable open" state, then height: auto, so it should be properly opened from the start.

I also suggest trying v5 that is now published as @nkbt/react-collapse. Also check examples dir, it has pre-opened case in there, because it is quite a common case.

I cannot help you with your case at this point until you give some codepen to have a look at.

Cheers!

KovDimaY commented 5 years ago

Actually, I am also having problems with the initial render... :(

Even if I hardcode my component to be always isOpened={true} - on the first render it is collapsed: image

The output looks like this: image

A curious thing is that when I click the <Header>, the collapse opens (as setState triggers a new render) and after this never changes (as the isOpened={true} is hardcoded): image

As a workaround for this problem I have done this: image

Now everything works correctly (all the components are rendered openned) but the problem is that on the initial render it shows the animation of openning. So it does not appear as openned but as opening and it is something that I do not want.

Some ideas why it can happen?

nkbt commented 5 years ago

@KovDimaY I can only help if I have some example to work with. codepen/codesandbox would be the way to go.

Your workaround is definitely not the way to go, since it just automatically opens it on start. Which triggers animation.

nkbt commented 5 years ago

Possible problem would be that component that contains collapse has height 0 on load. Sometimes it is due to absolute/relative positioning in css, sometimes it is due to collapse content to be empty... The main problem stays the same - on initial load collapse determines content to have 0 height. You can log it in render() and see yourself.

Even on collapse v5 it would not be fixed then. And you would have the same issue with initial animation to open state. Even using pure css animation.

KovDimaY commented 5 years ago

@nkbt Thank you for the fast answer!

The main problem is that when I try it in codepen/codesandbox it works fine, but just the same code does not work in my project... 😭 This is the code as I have in my project: https://codesandbox.io/s/z62o9poyzp

When I log it in the codesandbox - I see this: image

When I log it in my project - I see this: image

Looks like initially both cases have height 0 (even though I put the height of the child element of the collapse to be 200px), but in the case of codesandbox it continues to do something in my project it just stops... 🤔

I do not understand the reason why it can happen... 😞

nkbt commented 5 years ago

It is purely a CSS/DOM problem and most likely your component does not work because of a context it is in. flexbox, absolute position, etc. You can carefully check all the components up to the top of the tree to see which one causes the issue. I did have some issues like that, and it takes a while to find the real problem.

mr-amirganishaikh commented 5 years ago

@KovDimaY did you found the solution to it as I am also facing the same issue and for me, my collapse is wrapped under a form which doesn't have any position or display property applied on it

Adding attachment of React code structure and stylesheet code @nkbt can you please update on as what problem you found and what all to be checked.

screen shot 2019-01-31 at 11 23 01 pm

screen shot 2019-01-31 at 11 20 32 pm

p-selivanov commented 5 years ago

I had the same issue. My component is quite deep in the component tree and some of the parents use flex layout. Probably it is the reason of height = 0 on the initial measure.

Here is the solution that I came up with. Hope it will help somebody.

Note the use of isMeasured field.

export default class FilterGroup extends React.Component<Props, State>{

    readonly state: Readonly<State> = {
        isExpanded: true,
    };

    isMeasured: boolean = false;

    handleExpandClick = () => {
        this.setState(({ isExpanded }) => ({ isExpanded: !isExpanded }));
    }

    handleCollapseMeasure = (size: { width: number, height: number }) => {
        if (size.height > 0) {
            this.isMeasured = true;
        }
    }

    render() {

        return (
            <div className="filter-group">

                <div
                    className="group-header"
                    onClick={this.handleExpandClick}
                >
                    {this.props.title}
                </div>

                <Collapse
                    isOpened={this.state.isExpanded}
                    springConfig={{ stiffness: 400, damping: 40 }}
                    onMeasure={this.handleCollapseMeasure}
                    style={this.isMeasured ? undefined : { height: 'auto' }}
                >
                    <div className="group-content">
                        {this.props.children}
                    </div>
                </Collapse>
            </div>);
    }
}
nkbt commented 4 years ago

As new react-collapse@5.0.0 is released https://github.com/nkbt/react-collapse/releases/tag/v5.0.0 this issue has been most likely already solved.

Please feel free to re-open if the issue persists