Code Monkey home page Code Monkey logo

react-collapse's Introduction

react-collapse npm

Gitter

CircleCI Dependencies Dev Dependencies

Component-wrapper for collapse animation for elements with variable (and dynamic) height

React Collapse

Demo

http://nkbt.github.io/react-collapse

Codepen demo

http://codepen.io/nkbt/pen/MarzEg

Installation

NPM

npm install --save react-collapse

yarn

yarn add react-collapse

1998 Script Tag:

<script src="https://unpkg.com/react/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-collapse/build/react-collapse.min.js"></script>
(Module exposed as `ReactCollapse`)

Usage

1. Add a CSS transition

.ReactCollapse--collapse {
  transition: height 500ms;
}

IMPORTANT: Without adding a CSS transition there will be no animation and component will open/close instantly.

2. Content is always mounted (default)

import {Collapse} from 'react-collapse';

// ...
<Collapse isOpened={true || false}>
  <div>Random content</div>
</Collapse>

3. Content unmounts when collapsed

Use Unmount component provided as:

import {UnmountClosed} from 'react-collapse';

// ...
<UnmountClosed isOpened={true || false}>
  <div>Random content</div>
</UnmountClosed>

Example example/App/AutoUnmount.js


4. Controlled and accessible

If you want a controlled and accessible implementation, check out this example

Options

isOpened: PropTypes.boolean.isRequired

Expands or collapses content.

children: PropTypes.node.isRequired

One or multiple children with static, variable or dynamic height.

<Collapse isOpened={true}>
  <p>Paragraph of text</p>
  <p>Another paragraph is also OK</p>
  <p>Images and any other content are ok too</p>
  <img src="nyancat.gif" />
</Collapse>

theme: PropTypes.objectOf(PropTypes.string)

It is possible to set className for extra div elements that ReactCollapse creates.

Example:

<Collapse theme={{collapse: 'foo', content: 'bar'}}>
  <div>Customly animated container</div>
</Collapse>

Default values:

const theme = {
  collapse: 'ReactCollapse--collapse',
  content: 'ReactCollapse--content'
}

Which ends up in the following markup:

<div class="ReactCollapse--collapse">
  <div class="ReactCollapse--content">
    {children}
  </div>
</div>

IMPORTANT: these are not style objects, but class names!

onRest, onWork: PropTypes.func

Callback functions, triggered when animation has completed (onRest) or has just started (onWork)

Both functions are called with argument:

const arg = {
  isFullyOpened: true || false, // `true` only when Collapse reached final height
  isFullyClosed: true || false, // `true` only when Collapse is fully closed and height is zero
  isOpened: true || false, // `true` if Collapse has any non-zero height
  containerHeight: 123, // current pixel height of Collapse container (changes until reaches `contentHeight`)
  contentHeight: 123 // determined height of supplied Content
}
<Collapse onRest={console.log} onWork={console.log}>
  <div>Container text</div>
</Collapse>

Example example/App/Hooks.js

initialStyle: PropTypes.shape

initialStyle: PropTypes.shape({
  height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  overflow: PropTypes.string
})

You may control initial element style, for example to force initial animation from 0 to height by using initialStyle={{height: '0px', overflow: 'hidden'}}

IMPORTANT Any updates to this prop will be ignored after first render. Default value is determined based on initial isOpened value:

  initialStyle = props.isOpened
    ? {height: 'auto', overflow: 'initial'}
    : {height: '0px', overflow: 'hidden'};

Example: example/App/ForceInitialAnimation.js

checkTimeout: PropTypes.number

Number in ms.

Collapse will check height after thins timeout to determine if animation is completed, the shorter the number - the faster onRest will be triggered and the quicker height: auto will be applied. The downside - more calculations. Default value is: 50.

Pass-through props

IMPORTANT Collapse does not support any pass-through props, so any non-supported props will be ignored

Because we need to have control over when Collapse component is updated and it is not possible or very hard to achieve when any random props can be passed to the component.

Behaviour notes

  • initially opened Collapse elements will be statically rendered with no animation. You can override this behaviour by using initialStyle prop

  • due to the complexity of margins and their potentially collapsible nature, ReactCollapse does not support (vertical) margins on their children. It might lead to the animation "jumping" to its correct height at the end of expanding. To avoid this, use padding instead of margin. See #101 for more details

Migrating from v4 to v5

v5 was another complete rewrite that happened quite a while ago, it was published as @nkbt/react-collapse and tested in real projects for a long time and now fully ready to be used.

In the most common scenario upgrade is trivial (add CSS transition to collapse element), but if you were using a few deprecated props - there might be some extra work required.

Luckily almost every deprecated callback or prop has fully working analogue in v5. Unfortunately not all of them could maintain full backward compatibility, so please check this migration guide below.

1. Change in behaviour

New Collapse does not implement animations anymore, it only determines Content height and updates Collapse wrapper height to match it. Only after Collapse height reaches Content height (animation finished), Collapse's style is updated to have height: auto; overflow: initial.

The implications is that you will need to update your CSS with transition:

.ReactCollapse--collapse {
  transition: height 500ms;
}

IMPORTANT: Without adding a CSS transition there will be no animation and component will open/close instantly.

2. New props or updated props

  • onRest/onWork callbacks (see above for full description). Though onRest did exist previously, now it is called with arguments containing few operational params and flags.

  • initialStyle you may control initial element style, for example to force initial animation from 0 to height by using initialStyle={{height: '0px', overflow: 'hidden'}} IMPORTANT Any updates to this prop will be ignored after first render. Default value is:

      initialStyle = props.isOpened
        ? {height: 'auto', overflow: 'initial'}
        : {height: '0px', overflow: 'hidden'};
  • checkTimeout number in ms. Collapse will check height after thins timeout to determine if animation is completed, the shorter the number - the faster onRest will be triggered and the quicker height: auto will be applied. The downside - more calculations. Default value is: 50.

3. Deprecated props (not available in v5)

  • Pass-through props - any unknown props passed to Collapse component will be ignored

  • hasNestedCollapse - no longer necessary, as v5 does not care if there are nested Collapse elements, see example/App/Nested.js

  • fixedHeight - no longer necessary, just set whatever height you need for content element and Collapse will work as expected, see example/App/VariableHeight.js

  • springConfig - as new Collapse relies on simple CSS transitions (or your own implementation of animation) and does not use react-collapse, springConfig is no longer necessary. You can control control animation with css like

    .ReactCollapse--collapse {
      transition: height 500ms;
    }
  • forceInitialAnimation - you can use new prop initialStyle={{height: '0px', overflow: 'hidden'}} instead, so when new height will be set after component is rendered - it should naturally animate.

  • onMeasure - please use onRest and onWork instead and pick contentHeight from argument

    <Collapse
      onRest={({contentHeight}) => console.log(contentHeight)}
      onWork={({contentHeight}) => console.log(contentHeight)}>
      <div>content</div>
    </Collapse>
  • onRender - since animations are fully controlled by external app (e.g. with CSS) we no draw each frame and do not actually re-render component anymore, so it is impossible to have onRender callback

Development and testing

Currently is being developed and tested with the latest stable Node on OSX.

To run example covering all ReactCollapse features, use yarn start, which will compile example/Example.js

git clone [email protected]:nkbt/react-collapse.git
cd react-collapse
yarn install
yarn start

# then
open http://localhost:8080

Tests

# to run ESLint check
yarn lint

# to run tests
yarn test

License

MIT

react-collapse's People

Contributors

advyth avatar andarist avatar baransu avatar butenkot avatar dantman avatar davidspiess avatar forresst avatar frumcheg avatar glauberramos avatar greenkeeperio-bot avatar holi0317 avatar ivan-gerasin avatar jdeal avatar jooj123 avatar kerumen avatar kjetilsbl avatar mattgmarcus avatar meriadec avatar nkbt avatar npmcdn-to-unpkg-bot avatar nutgaard avatar oyvinmar avatar reintroducing avatar spaintrain avatar staticskies avatar vramana avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-collapse's Issues

Instantly collapses on first collapse

I have a component list and each item could have a set of children react-collapse wraps the children component. When I collapse an item the first time it collapses instantly and after that it works fine.
it is really noticeable when my component in the list has a button that can toggle the status if that item to enable or disable, and when I toggle any item for the first time all children collapse instantly and then reopen, but the state of it being opened was never changed.
It seems that it is happening on the first state change update after it was initialized. If I change isOpened to be false by default it is not an issue

Input loses focus on initially opened element

Triggering a rerender with an input onChange handler will make the input lose focus. Subsequent changes won't. Repro here: https://jsbin.com/ziquwaragi/1/edit?js,output

On the first render there's no <ReactMotion> wrapping the div. On the second render there is <ReactMotion> wrapping the div, so react does not reuse the <div> dom node from the previous render containing the input, so the input loses focus.

instantly collapses if rerendered during collapse

I'm trying to implement an accordion component with react-collapse. The issue is that if I call setState to collapse an element, then call setState again shortly after but before the first collapse finishes, the first collapse animation finishes right away.

Here's a repro: https://jsbin.com/viwalageta/edit?js,output

Clicking on Header 2 shows what I mean.

Not sure if this is an issue with react-collapse or react-motion.

Setting dynamic height to 'auto'

I'm using Collapse plugin to create a collpasable div. It works but it doesn't animate. I think it is because the plugin set the height to 'auto'. Why this happens? Can I fix it without setting the height manually?

<Collapse isOpened={this.props.isVisible}>
    <div id="bigPictureAccordion">
        <div className="col-sm-5">
            <div className="text">
                <div className="head">
                    Welcome <a className="name" href="">{this.props.user}</a>
                </div>
                <div dangerouslySetInnerHTML={{__html: this.props.text}}/>
            </div>
        </div>
        <!-- the following div contains background image -->
        <div className="col-sm-7 no-padding coverImg"></div>
    </div>
</Collapse>

Investigate possibility to use `context` for nested Collapse

Context is parent-to-child, though it should be possible possible to pass-through callback and invoke parent's function.
It is quite ugly, but will allow to notify parent Collapse that it has child one that started to open/close.

Should eliminate the need in hasNestedCollapse flag at all.

Should also fix non-interruptible animation of parent Collapse when child Collapse animation is triggered while parent't is not yet finished.

slide Up

how to revert it, to slide Up not down.

Jumps to zero height and flickers from zero to X height

Hi,
When a Collapse component contains an element with a dynamic height that starts/ends at 0, it causes the Collapse component to jump instead of animate. I believe the following licecap demonstrates the same issue. There's also a flicker when going from 0 to 50.
react-collapse-bugs

Npm warning for node 4

npm warns that node v5 is required from your package, because package.json specifies:

"engines": {
    "node": "^5.0.0"
  }

IMO it should be node: "^4.0.0". Node v5 has new experimental features, while v4 is the stable, mature release branch. If you do not make use of any new features it is simply not necessary to restrict your library to the v5 release branch.

TransitionMotion

Do you think it would work to use TransitionMotion?

I have some dynamic content basic on flux data and I would like to be able to get rid of the content but still have it visible while it is closing.

Basic usage failing

Thanks for this project!

When I wrap a tag in an otherwise working render() function:

import { Collapse } from 'react-collapse';
...
return (
                <Collapse isOpened={true}>
                    <h3>Cars</h3>
                </Collapse>
            );

I get:
Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components).

Dependencies installed, Babel 6 / ES6, webpack build...

Wrong height calculated in nested components

Hello.
I found a strange behavior with react collapse when you dont wrap the content inside a div with padding > 0.

The problem appears inside my sidebar menu.

I took the Nested.js from the examples and modified it. So it should be easy to reproduce it.

This code works:

        <Collapse
          style={style.container}
          isOpened={isOpened}
          keepCollapsedContent={keepContent}>
            <div style={{padding: 1}}>
              <ul>
                <li>Hallo
                  <ul>
                    <li>
                      <VariableHeight />
                    </li>
                  </ul>
                </li>
              </ul>
            </div>
        </Collapse>

This one calculates the height wrong and jumps the the right size after animation is finished.

        <Collapse
          style={style.container}
          isOpened={isOpened}
          keepCollapsedContent={keepContent}>            
              <ul>
                <li>Hallo
                  <ul>
                    <li>
                      <VariableHeight />
                    </li>
                  </ul>
                </li>
              </ul>            
        </Collapse>

Here's how it looks.
react_collapse_jumping

Thank you in advance. :)

Callstack error with nested collapse elements

I have following nested collapse boxes:

RoomSelection Collapse Box
   - Offer Collapse Box 1
          - Room Collapse Box 1
          - Room Collapse Box 2
          - Room Collapse Box 3
   - Offer Collapse Box 2
         ....

If i toggle more then one of the room collapse boxes i get a Uncaught RangeError: Maximum call stack size exceeded error and it takes aprox. 5 seconds until it opens. See gif

gif

Any ideas what could cause this?
Not nested collapse elements work just fine.

No animation after update

After updating from 2.0.0 to 2.1.0, the <Collapse> component opens and closes as expected, but doesn't animate anymore.

Add an option to avoid initial render of content

Currently the following will log I am being rendered.

const MyComponent = React.createClass({render: () =>
  console.log('I am being rendered') || <span>content</span>
});

<Collapse isOpened={false}>
  <MyComponent />
</Collapse>

In case of many initially collapsed elements, it can be a considerable performance penalty to render all collapsed content.

An option could determine if these should be initially rendered.
Although I'm not sure why someone would want to initially render a hidden element.

Alternatively, a solution would be to implement #19 as an option. The following construct would then achieve the wished behavior.

let isOpened = false;
<div>
  { isOpened && <Collapsed isOpened={isOpened} initallyAnimate={true}>content</Collapse>}
</div>

Thanks for <Collapase/> btw :-)

Calculate margins

Margins that spill out of the container are not taken into account in the height calculation. I know Velocity handles this by just animating the margin, which can be done, but wanted to see how you feel about this.

React Collapse in A list causes all collapsed items to open when one is clicked

This might not be a bug so much as user error, but if you render multiple:

import Collapse        from 'react-collapse';

...

<Collapse isOpened={this.props.hidden}>
  ... 
</Collapse>

in a list, and then click on one item in the list to trigger it to open, ALL of them will open. Not sure the best approach to get around this. Is there some option or some way where I can say if X is clicked then only open X and not Y and Z

Unnecessary unmount with keepCollapsedContent

Im not 100% convinced this is an issue with react-collapse (maybe react-motion?)

I have noticed that when using the keepCollapsedContent, the first time you open - any child components are rendered and then unmounted - but any subsequent open/close there is no longer any unmounting.

Ideally it would never unmount so we dont need another unnecessary rerender after that

Re-render nested components

ReactCollapse re-render childrens on first animation.

  1. Have a nested component with some initial state
  2. Change state of this component by UI control
  3. Click on toggle
  4. Nested component rendered again with initial state

Look:
example

Touch: http://codepen.io/Frumcheg/pen/pyPzEm

I think, this happend because method render() can return 2 differend classes.
When ReactCollapse mounted, div returned, when i click on toggle, <Motion> returned instead.
First solution for me is keep state between mount/unmount in outer variable, or in top level component, but this not best way.
Is it possible always return <Motion> class? Why react collapse has flag renderStatic inside?

Collapse with nested Collapse is kept forever in WAITING state

From #34 (comment)

The solution for now is to not pass any props through parent collapse if only children are changed (so children should be connected to a flux/redux store or something). Now when props of paren collapse are changed it is transitioned to state WAITING, which locks its height. Since it is own height is not changed after that (because children are expanded with animation, so the next step height is exactly as it was before) - it may forever stay in this state =(.

So it works perfectly when children are expanded instantly (no nested collapse), but not working when collapse elements are nested.

I consider adding a flag hasNestedCollapse to skip this transition to WAITING state. This way everything would work perfectly since it has height: auto.

Optimize react-collapse when height is static and known ahead

For perf matter if height is known we can simplify output avoiding additional height checks, but keeping same clean API.

I imagine this to be used like:

  1. Dynamic height API

    <Collapse isOpened={true || false}>
    <div>Random content</div>
    </Collapse>
  2. Static height API

    <Collapse isOpened={true || false} height={100}>
    <div>Random content</div>
    </Collapse>

`onRest` not being called

I am using Collapse with ES6 in my project and it is working so far.
However the onRest callback is not being called.

I am using:

<Collapse className="VenueContentMap" onRest={() => console.log('rest')}  isOpened={isMapShown} fixedHeight={400}>
</Collapse>

Might it be a react-motion issue?

This project is very much appreciated btw, reminds of the jQuery.slideToggle days :)

Make <Collapse/> render a givent DOM element instead of just a div

Using <Collapse/> in a <ul> based menu, or inside a native inline element, i.e <span/>'s is not semantically correct. This will also apply if react-collapse is to be used instead of a <nav/> element, rendering a <div/> instead of the semantically correct <nav/> element.

Is there a way to bypass this at the project current state, or should we wait for a PR/fix from the owner?

Collapse "jumps" as it nears the end of an animation

react-collapse-glitchiness

This seems to happen everywhere I use it..

<h1>Mass Text</h1>
  <TextComposer message={this.state.message} onChange={this._handleMessageUpdate} />
  <TestPanel>
    <Collapse isOpened={!this.state.text_message_approved && this.state.message.length > 0}>
      <hr />
      <h3>Next Step: Testing</h3>
      <div className="form-group">
        My Cellphone
        <select className="form-control" onChange={this._handleSendTestTo} value={this.state.user_to_send_test_to}>
        { this.state.proup_team_members.map(
          (team_member, index)=>(
            <option value={index} key={index}>{team_member.last_name} {team_member.location.cell_phone_carrier}</option>
            ) 
          )}
        </select>  
      </div>
      <div className="form-group">
      <a href="#" className="btn btn-proup-black-background-white" onClick={this._handleSendTestText}>Send Test Text</a>
      </div>
    </Collapse>
    <Collapse isOpened={this.state.message.length > 0}>
      <div className="form-group">
      Text Message Looks Good On My Phone <input onChange={this._handleTextMessageApproved} className="form-control" type="checkbox" name="" />
      </div>
    </Collapse>
  </TestPanel>
  <AdvancedPanel>
    <Collapse isOpened={this.state.text_message_approved}>
      <h3>Next Step: Send It Out</h3>

      <div className="form-group">
      Advanced <input id="advanced-check" onChange={this._handleAdvancedChecked} className="form-control" type="checkbox" name="" />
      </div>
        <Collapse isOpened={this.state.show_advanced_panel}>
          <div>
            <div className="form-group">
            <select className="form-control" 
            onChange={this._handleProviderFilter} 
            value={this.state.providers}>
            <option value="all">All Providers</option>
            <option value="tmobile">T-Mobile Only</option>
            <option value="not-tmobile">All But T-Mobile</option>
            </select>
            </div>
            <div className="form-group">
            Send, Starting From ID
            <input className="form-control" type="text" onChange={this._handleStartingId} value={this.state.starting_id} />
            </div>
          </div>
        </Collapse>
    </Collapse>
  </AdvancedPanel>
  <SendPanel>
    <Collapse isOpened={this.state.text_message_approved}>

        <div className="form-group">
          <div><a href="#" className="btn btn-proup-black-background-white" onClick={this._handleSendMassText}>Send Mass Text</a><br /><br /></div>
          <div><a href="#" className="btn btn-proup-black-background-white" onClick={this._handleCancelSending}>Cancel Sending</a></div>
        </div>
    </Collapse>
  </SendPanel>
  </div>`

Prop for onHeightChange

Thanks for the awesome component! I'm trying to use this inside of an absolutely positioned modal which is centered on the screen. When the Collapse component expands, I need to re-center my modal. Ideally the re-centering should happen each time the spring renders so the modal smoothly moves up as the content grows longer.

I can't think of any way to do that except to pass a function into the Collapse component for it to call each time the interpolated height changes.Any other thoughts on how I could approach this?

Thanks,
Jeff

springConfig doesn't work (?)

The springConfig doesn't seem to change the spring when you pass in an object.

<Collapse
  isOpened={this.props.expanded}
  springConfig={[400, 25]}
>
  // ....
</Collapse>

However, passing in something like { stiffness: 400, damping: 25 } works (?).

Edit: Okay I know the problem. I have the latest version of react-motion installed. New spring() now accepts an object (like the one I mentioned above) instead of [stiffness, damping].

Height problem

I have Collapase component which wraps my SubOrder component:

             <Collapse
               class="panel-body"
               onHeightReady={(height) => {console.log(height)}}
               isOpened={!collapsed}
               springConfig={presets.noWobble}
             >
               <SubOrder
                 prices={prices}
                 shippingAddress={shippingAddress}
                 {...subOrder}
               />
             </Collapse>

The problem is that height returns 0 so animations are not working correctly. When i'm looking at Chrome DevTools there is div which is wrapping my component but it has no height so i think it's breaking height calculation. And when I'm inspecting page with React DevTools the same div has ref=bound setWrapperRefs(). Am I doing something wrong or it's some react-collapse/react-height bug?

EDIT: And also there in no onRest event emitted


screen shot 2016-08-04 at 23 33 10


screen shot 2016-08-04 at 23 32 29

re-animation on re-render

Now on a few occasions a react re-render causes the animation to re-run (the end bit of it at least).
Unfortunately I cannot reliably reproduce it yet.

It's a bit weird. I have the redux store changing (of course that causes a re-render) but nothing related to react-collapse changes.

Nested <Collapse/>s, parent <Collapse/> is also changed

Probably not quite related to #58, but related to #40.

import React, { Component, PropTypes } from 'react';
import { IndexLink, Link } from 'react-router';
import Collapse from 'react-collapse';

export default class Menu extends Component {

  static propTypes = {
    isMenuToggled: PropTypes.bool.isRequired
  };

  constructor(props){
    super(props);

    this.state = {
      isSubMenuToggled: false
    };
  }

  render() {

    const { isSubMenuToggled } = this.state;
    const { isMenuToggled } = this.props;

    return (
      <nav ref="menu" className="menu" role="navigation">
        <Collapse key="menuCollapse" keepCollapsedContent={true} isOpened={isMenuToggled}>
          <ul className="menu-list mypages-nav-active">
            <li className="menu-item menu-mainItem is--parent">
              <Collapse key="subMenuCollapse" className="menu-main" isOpened={isSubMenuToggled} keepCollapsedContent={true}>
                <ul className="menu-sublist">
                  <li className="menu-item">
                    <span className="menu-row">
                      <IndexLink activeClassName="is--active" className="menu-link" to="/">
                        Overview
                      </IndexLink>
                    </span>
                  </li>
                </ul>
              </Collapse>
            </li>
          </ul>
        </Collapse>
      </nav>
    );
  }
}

When using nested <Collapse/>s, if I open the inner <Collapse/>, the outer <Collapse/>'s height is also adjusted.

"Maximum call stack size exceeded" when passing "display: flex" into "style"

Just adding display: 'flex' to the style prop of the Collapse causes "Uncaught RangeError: Maximum call stack size exceeded".

From my investigation, the infinite recursion is caused by the setState call in the onHeightReady callback which is called from within a setState callback (from react-height).

Repro: http://codepen.io/anon/pen/WrYBbP?editors=101
Just click "Toggle" on the first example and look into the console.

This may be an issue of react-height or even react itself. I'm not sure what to do with that, so reporting here first.

Component Seems to Disappear for a Brief Second


gif

Component seems to disappear or flicker for a brief second even before isOpened is set to false. In the example above, when I close the Message component, it fades out and then after, isOpened is set to false; Something funky seemed to be happening toCollapse when the close icon is clicked.

Message.js

import React, {PropTypes, Component} from 'react';
import MessageTypes from '../constants/MessageTypes';
import Collapse from 'react-collapse';

export default class Message extends Component {

    constructor(props, context) {
        super(props, context);
        this.handleClick = this.handleClick.bind(this);
        this.onAnimationEnd = this.onAnimationEnd.bind(this);
        this.state = {
            animate: false,
            hide: false
        }
    }

    handleClick(e) {
        e.preventDefault();
        this.setState({animate: true});
    }

    onAnimationEnd() {
        this.setState({hide: true});
    }

    render() {
        return (
            <Collapse isOpened={!this.state.hide}>
                <div onAnimationEnd={this.onAnimationEnd} className={`card message ${this.state.animate ? 'message-transition-fade-out' : ''}`}>
                    <span className={`icon icon-${this.iconLevel()}`} style={{color: `#${this.iconColor()}`}}></span>
                    <p>
                        <strong>{this.props.title}</strong><br />
                        <span dangerouslySetInnerHTML={{ __html: this.props.message }} />
                    </p>
                    <a href="#" onClick={this.handleClick}>
                        <span className="icon icon-close"></span>
                    </a>
                </div>  
            </Collapse>
        );
    }

}

Message.scss

.message {
    &-transition {
        &-fade-out {
            @include animation(0s, 3s, fadeout);
        }
    }
}

Event triggers for completing collapse and expand

I've found a use case where it would be useful to have optional onCollapseComplete and onExpandComplete callbacks.

If other people would find this useful then I'd be happy to implement it properly and raise a PR

You need to detect window resize events

And recalculate height or set dirty flag on window resize.

window.addEventListener('resize', this._onWindowResize);
// don't forget to unsubscribe
window.removeEventListener('resize', this._onWindowResize);

Also there must be some kind of refresh method for situations like next:
First component rendering occurs inside element with display:none style
a lot of tab controls use display:none style
Height is always be zero inside such elements.

So without some kind of manual refresh it will be impossible to use this component.

Good Work!!! I like this.

Remove peerDependencies?

I was trying to install react-collapse with npm@3 and Webpack build failed, because I didn't have react-motion installed (npm@3 doesn't install peerDependencies).

Do you think we could remove peerDependencies? I think we don't need react as well, because it is already included in dependencies.

Usage with react-router?

Any advice to use this component to display react-router routes? I'd like to render the router content and then expand it with collapse (and vice versa)

reusable collapse component firing incorrectly

Place an instance of collapse in a component, and initiate it twice. Set one to open, the other closed.

On page load, toggle the closed button - this will fire the open state to 'reopen'.

Behaviour only seems to happen when reusing the collapse component, not on multiple single instances.

Specify a 'collapse height'

Hey, love this!!
just wondering if it'd be possible to set a collapse height, so that instead of collapsing to 0, it could be Xpx high still? I'd like to use it as a text truncation / minimization tool

Thanks :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.