Code Monkey home page Code Monkey logo

react-collapsible's Introduction

Npm Version License Downloads Per Week

React Responsive Collapsible Section Component (Collapsible)

React component to wrap content in Collapsible element with trigger to open and close.

Alt text

It's like an accordion, but where any number of sections can be open at the same time.

Supported by Browserstack.

Browserstack Logo


Migrating from v1.x to v2.x

Version 2 is 100% API complete to version 1. However, there is a breaking change in the onOpen and onClose callbacks. These methods now fire at the end of the collapsing animation. There is also the addition of onOpening and onClosing callbacks which fire at the beginning of the animation.

To migrate to v2 from v1 simply change the onOpen prop to onOpening and onClose to onClosing.

Installation

Install via npm or yarn

npm install react-collapsible --save

yarn add react-collapsible

Usage

Collapsible can receive any HTML elements or React component as it's children. Collapsible will wrap the contents, as well as generate a trigger element which will control showing and hiding.

import React from 'react';
import Collapsible from 'react-collapsible';

const App = () => {
  return (
    <Collapsible trigger="Start here">
      <p>
        This is the collapsible content. It can be any element or React
        component you like.
      </p>
      <p>
        It can even be another Collapsible component. Check out the next
        section!
      </p>
    </Collapsible>
  );
};

export default App;

With a little CSS becomes

Alt text

Properties (Options)

contentContainerTagName | string | default: div

Tag Name for the Collapsible Root Element.

containerElementProps | object

Pass props (or attributes) to the top div element. Useful for inserting id.

trigger | string or React Element | required

The text or element to appear in the trigger link.

triggerTagName | string | default: span

The tag name of the element wrapping the trigger text or element.

triggerStyle | object | default: null

Adds a style attribute to the trigger.

triggerWhenOpen | string or React Element

Optional trigger text or element to change to when the Collapsible is open.

triggerDisabled | boolean | default: false

Disables the trigger handler if true. Note: this has no effect other than applying the .is-disabled CSS class if you've provided a handleTriggerClick prop.

triggerElementProps | object

Pass props (or attributes) to the trigger wrapping element. Useful for inserting role when using tabIndex.

As an alternative to an auto generated id (which is not guaranteed to be unique in extremely fast builds) that is used as the TriggerElement id, and also as a separate aria-labelledby attribute, a custom id can be assigned by providing triggerElementProps with an object containing an id key and value, e.g. {id: 'some-value'}.

contentElementId | string

Allows for an alternative to an auto generated id (which is not guaranteed to be unique in extremely fast builds) that is used as part of the component id and the aria-controls attribute of the component.

transitionTime | number | default: 400

The number of milliseconds for the open/close transition to take.

transitionCloseTime | number | default: null

The number of milliseconds for the close transition to take.

easing | string | default: 'linear'

The CSS easing method you wish to apply to the open/close transition. This string can be any valid value of CSS transition-timing-function. For reference view the MDN documentation.

open | bool | default: false

Set to true if you want the Collapsible to begin in the open state. You can also use this prop to manage the state from a parent component.

accordionPosition | string

Unique key used to identify the Collapse instance when used in an accordion.

handleTriggerClick | function

Define this to override the click handler for the trigger link. Takes one parameter, which is props.accordionPosition.

onOpen | function

Is called when the Collapsible has opened.

onClose | function

Is called when the Collapsible has closed.

onOpening | function

Is called when the Collapsible is opening.

onClosing | function

Is called when the Collapsible is closing.

onTriggerOpening | function

Is called when the Collapsible open trigger is clicked. Like onOpening except it isn't called when the open prop is updated.

onTriggerClosing | function

Is called when the Collapsible close trigger is clicked. Like onClosing except it isn't called when the open prop is updated.

lazyRender | bool | default: false

Set this to true to postpone rendering of all of the content of the Collapsible until before it's opened for the first time

overflowWhenOpen | enum | default: 'hidden'

The CSS overflow property once the Collapsible is open. This can be any one of the valid CSS values of 'hidden', 'visible', 'auto', 'scroll', 'inherit', 'initial', or 'unset'

contentHiddenWhenClosed | bool | default: false

Set this to true to add the html hidden attribute to the content when the collapsible is fully closed.

triggerSibling | element | default: null

Escape hatch to add arbitrary content on the trigger without triggering expand/collapse. It's up to you to style it as needed. This is inserted in component tree and DOM directly after .Collapsible__trigger

tabIndex | number | default: null

A tabIndex prop adds the tabIndex attribute to the trigger element which in turn allows the Collapsible trigger to gain focus.

CSS Class String Props

classParentString | string | default: Collapsible

Use this to overwrite the parent CSS class for the Collapsible component parts. Read more in the CSS section below.

className | string

.Collapsible element (root) when closed

openedClassName | string

.Collapsible element (root) when open

triggerClassName | string

.Collapsible__trigger element (root) when closed

triggerOpenedClassName | string

.Collapsible__trigger element (root) when open

contentOuterClassName | string

.Collapsible__contentOuter element

contentInnerClassName | string

.Collapsible__contentInner element

CSS Styles

In theory you don't need any CSS to get this to work, but let's face it, it'd be pretty rubbish without it.

By default the parent CSS class name is .Collapsible but this can be changed by setting the classParentString property on the component.

The CSS class names follow a type of BEM pattern of CSS naming. Below is a list of the CSS classes available on the component.

.Collapsible

The parent element for the components.

.Collapsible__trigger

The trigger link that controls the opening and closing of the component. The state of the component is also reflected on this element with the modifier classes;

  • is-closed | Closed state
  • is-open | Open setState
  • is-disabled | Trigger is disabled

.Collapsible__contentOuter

The outer container that hides the content. This is set to overflow: hidden within the javascript but everything else about it is for you to change.

.Collapsible__contentInner

This is a container for the content passed into the component. This keeps everything nice and neat and allows the component to do all it's whizzy calculations.

If you're using a CSS framework such as Foundation or Bootstrap, you probably want to use their classes instead of styling .Collapsible. See Properties above.

Example

Examples of <Collapsible /> components can be found in the ./example folder. To get the example running:

cd example && yarn && yarn start

This will run a parceljs app.

Issues

Please create an issue for any bug or feature requests.

Here is a plain JSFiddle to use for replicating bugs.

Licence

React Responsive Collapsible Section Component is MIT licensed

react-collapsible's People

Contributors

alireza-mh avatar antoinetb avatar arye-eidelman avatar bowlingx avatar byrnedo avatar colinramsay avatar compojoom avatar conways-glider avatar cristiandan avatar dependabot[bot] avatar eneskilicaslan avatar erinrep avatar esalaza avatar evgenykochetkov avatar glennflanagan avatar goodmorninggoaway avatar justinr1234 avatar karltaylor avatar klaasvaak avatar koralarts avatar markuslund avatar mattbodey avatar nathanhere avatar omantere avatar roseaboyer avatar rosenfeld avatar rsarai avatar twintails avatar williamboman avatar y-yagi 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-collapsible's Issues

Maintainers Wanted

I'm finding increasingly difficult to keep up with maintaining react-collapsible so I'm looking for maintainers/collaborators so if you're up for some Open Source goodness then let me know in this issue. 👍

Proper use of triggerSibling

Hi,

I gave the Collapsible as trigger a component which consists of a

with 6 elements. My problem is that the last two elements are buttons, but I don't want that the Collapsible gets opened when clicking on them.

Is there any way to give down the triggerSibling prop to the "row"-class so that it doesn't get triggered when clicking on it?

Best,

Collapsibles never closing

I think I tracked it down to

onTransitionEnd=(this.handleTransitionEnd}

Never being fired. It was the parent Accordion I modified for my use, not your code!
Everything else seems to work apart from this trigger, and as such the two calls to setState are never being called.

Any ideas why this might be happening?
Cheers.

HTML in Collapsible Content

Hi Glenn,

Great component, thanks for sharing. In my case I have HTML as the Collapsible content. My trigger is a string, but the content below is HTML via a const, It would be awesome if the HTML could be rendered, rather than just showing the code. Any ideas on how I can make that work?

Thanks!

Height issues in IE11

The Collapsible__contentOuter class has height:auto, but in IE11 its getting a fixed height. This is causing problems for me as the content inside the collapsible component is dynamic and it has overflow: hidden.

Can be fixed easily with some custom CSS, but the height should behave consistently across all browsers.

NPM install does not install the latest code.

If I do a npm install react-collapsible I don't seem to get the latest version of Collapsible.js that I see in the development branch. For instance the onOpen does not exists in master The work around was to copy paste the latest Collapsible.js (development) in my project install the create-react-class dependency. Using the latest works with onOpen prop.

Problem using the component

hi
i'm trying to make collapse menu and I used your component
but when I click start here nothing happen and height always equal to 0px

can u help me

untitled

collapsible is not closing

Hello,

we have a very basic problem. We have imported the library and integrated your basic example. By clicking on start the menu opens but it does not close again. There is no way to let it close again. Did you experience this problem?

Thank you
Dennis

[docs] Unable to run the included example locally

Steps I followed:

  1. cloned the react-collapsible repo
  2. installed webpack and webpack-dev-server globally (although not necessary)
  3. cd'd into react-collapsible/ and did npm i
  4. run webpack-dev-server

Here are the errors:

ERROR in ./src/Collapsible.js
Module not found: Error: Can't resolve 'prop-types' in '/home/akshay.naik/Documents/react-collapsible/src'
 @ ./src/Collapsible.js 13:17-38
 @ ./example/_src/js/index.js
 @ multi (webpack)-dev-server/client?http://localhost:9000 ./example/_src/js/index.js

ERROR in ./example/_src/js/index.js
Module not found: Error: Can't resolve 'react' in '/home/akshay.naik/Documents/react-collapsible/example/_src/js'
 @ ./example/_src/js/index.js 3:13-29
 @ multi (webpack)-dev-server/client?http://localhost:9000 ./example/_src/js/index.js

ERROR in ./src/Collapsible.js
Module not found: Error: Can't resolve 'react' in '/home/akshay.naik/Documents/react-collapsible/src'
 @ ./src/Collapsible.js 9:13-29
 @ ./example/_src/js/index.js
 @ multi (webpack)-dev-server/client?http://localhost:9000 ./example/_src/js/index.js

ERROR in ./example/_src/js/index.js
Module not found: Error: Can't resolve 'react-dom' in '/home/akshay.naik/Documents/react-collapsible/example/_src/js'
 @ ./example/_src/js/index.js 7:16-36
 @ multi (webpack)-dev-server/client?http://localhost:9000 ./example/_src/js/index.js

overflowWhenOpen does not work

Im using overflowWhenOpen='visible' on an uncontrolled Collapsible, and it doesn't seem to do anything. It looks like the only reference to this property is when this.props.open is set. Is this property only supposed to work when the Collapsible is controlled?

Can't open/close by trigger node after change open prop

Description

If change status by two way which are trigger and open prop, unnecessary openCollapsible has been called.
after that, trigger does not work because transitionend will not be fired.

Already send pull request about it by other, it works for me.
Could you merge it?
#65

Reproduce process

  1. Click trigger text
  2. Click toggle button
  3. Can't open/close by trigger text

Details

  1. Click trigger text
    1.1. will open Collapsible(height=24px)
    1.2. transitionend will be occurred and height=auto
  2. Click toggle button
    2.1. call unnecessary openCollapsible from componentDidUpdate by changing open prop
    2.2. call continueOpenCollapsible and height=24px
    2.3. transitionend WILL NOT BE FIRED because already opened
  3. Can't open/close by trigger text
    3.1. call closeCollapsible and height=24px
    3.2. window.setTimeout WILL NOT BE CALLED because already height isn't auto
import React, { Component } from 'react'
import Collapsible from 'react-collapsible'

export class Sample extends Component {
  constructor() {
    super()
    this.state = { isOpen: false }
  }

  toggleCollapsible = () => {
    this.setState({ isOpen: !this.state.isOpen })
  }

  render() {
    return (
      <div>
        <Collapsible trigger="Trigger" open={this.state.isOpen}>
          <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit</div>
        </Collapsible>
        <input type="button" onClick={this.toggleCollapsible} value="Toggle" />
      </div>
    )
  }
}

export default Sample

close other siblings if one collapse will open

Hi there.

Could you do this logic: close other siblings if one collapse will open.

I'm facing this problem with many collapsible item in small popup. So, there is scrollable content, But if you open last one which is visible in modal, UI problem happens.

Change trigger text on state change?

I'd suggest adding the ability to change the trigger text on click. For example, so the text on the trigger can say "Open collapsible" when the div is collapsed and "Close collapsible" when it is open.

Style trigger and triggerSibling

Hi !

I think that so far it isn't possible to style trigger and triggerSibling under one div, your component produces two span that can't be related.

For example, I would like to create something like this :

.myTriggerStyle {
display: inline-flex;
justify-content: space-between;
}

My html output :
<div className="myTriggerStyle">
triggerElement //a span element with my trigger stuff
triggerSiblingElement // a span element with my triggerSibling stuff
</div>

But the first div parent that contains trigger and triggerSibling is the div that also contains all of my collapsible data, but I want their style to be different from the triggers styles.

How can I achieve this ?

Collapsible not compatible with embedded semantic Grid

Before I start whining about my issue, thanks for this component. I appreciate your contribution.

My issue is that I am wrapping a Grid that has Columns, using the Semantic UI React components.
When I wrap the Grid in Collapsible, the widths of the Grid's Columns are no longer honored. Something about Collapsible is overriding the css the Grid needs.

I would appreciate any suggestions on what to I can try. I may have to extract from your example and make my own if I can't figure this out.

Thanks again,
John

Collapsing/expanding all collapsible elements

Is it possible to use the .Collapsible__trigger and is-closed/is-open to make a collapse all function?
-- I tried using it with GetElementsByClassName and modifying it from is-closed to is open, but this didn't seem to do anything.

Have more than 1 data-trigger ?

Can we have more than 1 data trigger so, for example, if I pass
data-trigger={['text 1', 'text 2']}

it renders it as

<span class="Collapsible__trigger is-open">
  <span class="Collapsible__trigger--content-1"> text 1 </span>
  <span class="Collapsible__trigger--content-2"> text 2 </span>
</span>

Sharing styles on internal components

I'm using Sass to style my components.

Is it possible to add classNames to inner elements like .Collapsible__contentOuter and Collapsible__contentOuter? I'd like these elements to share some styles with other components on my app, and it doesn't feel to be right to add react-collapsible selectors .Collapsible__contentOuter and Collapsible__contentOuter to other unrelated SCSS files.

For instance, in my project I have different panels, and some are collapsible and some are not. I have a file called _panel.scss that looks like this:

`.panel {
&:not(:first-child) {
margin-top: 40px;
}

.panel-heading,
.Collapsible__trigger {
	display: block;
	position: relative;
	padding-bottom: 10px;
	border-bottom: solid 2px $gray-light;
	margin-top: 0;
	margin-bottom: 0;
}

.panel-body,
.Collapsible__contentInner {
	padding-top: 16px;
}

}`

That works fine, but I think I'd rather remove the Collapsible styles from there and add the panel-heading classNames to the Collapsible__trigger element, for example, but in React world as far as I know I have no access to that markup.

Any ideas or recommendations?

Adding icon and text to trigger

I know that someone asked if you can use an icon in the trigger property for the Collapsible tag.
But can you combine an image icon and text in the trigger props?

this is what I have currently:

so I can either do this (which displays the "text"
const sectionLabel = props.testResult.name + " - " + props.testResult.result; <Collapsible trigger={sectionLabel}

or I can do this (which displays the icon
const failed = props.testResult.result.toLowerCase() === "failed"; const img = failed ? "/images/x.png" : "/images/check.png"; <Collapsible trigger={<img src={img}/>}

but I don't see how to combine them?

Any chance of a minor release in the near future? Would love to take advantage of the open and close trigger hooks

Thanks for building and sharing this component. It works great for my needs. I've been using it on a local branch with my package.json pointing to a sha with the open/close triggers.
"react-collapsible": "git+ssh://[email protected]:glennflanagan/react-collapsible.git#1b6065a",

I am eagerly awaiting your next release. If there is any way I can help out to expedite that process, please let me know.

Thanks,

Joel

Collapsible descendants triggering onTransitionEnd

Noticed an issue where descendants of a collapsible container with css transitions (in this case a :hover transition) were bubbling up and causing handleTransitionEnd to fire. Noticed it when my onOpen handler was getting called a bunch.

Maybe checking the eventtarget in the handler function for the parent element could be a quick fix?

Thanks for the lib!

radio button label in Trigger area doesn't affect radio input

Hi,
Awesome component! appreciated!
I'm trying to add action element in trigger area like dropdown/radio buttons
each radio button have a label with "for" attribute - clicking on the label doesn't triggering the radio input change event.

Sample html inside trigger area:

<div class="radio-group">
    <div>
        <input type="radio" id="radio-input-xx" name="xxx" value="Standard_Application">
        <label class="radio-button-label standard-configuration" for="radio-input-xx">Standard</label>
    </div>
    <div>
        <input type="radio" id="radio-input-xx" name="xxx" value="Custom_Deployment">
        <label class="radio-button-label custom-configuration" for="radio-input-xx">Custom</label>
    </div>
</div>

Warning: React.createClass is deprecated

Just installed this module, and got the following error in the console.

Warning: Collapsible: React.createClass is deprecated and will be removed in version 16. Use plain JavaScript classes instead. If you're not yet ready to migrate, create-react-class is available on npm as a drop-in replacement.

Enable user selection of trigger wrapper (span currently) element to prevent div inside span

Hi, Glenn.

Thanks for this great component. The default trigger wrapper is a span element. This is great for when the user supplies only text as the trigger, but as the component also permits the use of arbitrary React elements, I guess it won't be uncommon for the user to supply divs, ending up with divs inside the span (invalid HTML).

I propose the creation of a new property named triggerComponent (or triggerElement) with 'span' as the default value (for backward compatibility) which can be used to specify other values such as ' div'.

PR: #57

Thank you.

Problem in testing with jest and react-test-renderer

I am trying to test the component with react-collapsible using jest and react-test-renderer. But it gives an type error saying "Cannot read property 'addEventListener' of null at componentDidMount (node_modules/react-collapsible/dist/Collapsible.js:105:20). What is the solution for this error?

I am using react with redux.

Problem with overflow on transition

Hello, I have a problem,

I have to be able to display menu lists, by default contentOuter is overflow: hidden, I overloaded to tell him that when you open you're overflow: visible, and when you close you're overflow: hidden,

The problem I have is when I decide to reopen the collapse, the text appears as it is in immediatly because it's -> overflow: visible,

There would be a possibility when you want to open it to overflow: auto and when finished it pass in overflow: visible?

Best regards !

Why i want overflow:visible
screen shot 2016-09-30 at 12 14 56

Why i need change state for overflow :
screen shot 2016-09-30 at 12 18 09

UNMET PEER DEPENDENCY [email protected]

`-- UNMET PEER DEPENDENCY [email protected]

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules\chokidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN [email protected] requires a peer of react-collapsible@^1.3.0 but none was installed.
npm ERR! code 1

lazyRender doesn't work without css

If you use lazyRender without css, then panel doesn't unfold until there have been three clicks. I believe this is because the height of the children is unknown until the first render, so the first click renders the children (but doesn't unfold because height is 0), the second click closes, then the third click finally unfolds correctly.

To reproduce this, delete the content of example/_src/sass/components/_Collapsible.scss, open the example and click on "What happens if there's a shed-load of content?" It should take three clicks to open properly.

If this isn't going to be changed, the documentation should indicate that some css is required for lazyRender to work.

Is it possible to programmatically close a collapsible?

I created a component that has several collapsibles. Inside each collapsible I have individual forms. Upon the submit of each form I would like to close the collapsible component and render the submitted form value in the label. Is it possible to programmatically close the collapsible based on an action (submit)?

Note: I did notice you have handleTriggerClick; however, this would only allow me to override what you are already doing for the open/close, which is functionality I do not want to lose.

Handling click only on part of the trigger component

Hello,

I have developed my own components for trigger and triggerWhenOpen. However, the panel collapses/opens whenever I click anywhere on the trigger panel.

I would like open/close only on clicks on specific elements of the trigger area - e.g. a link. I tried to implement this through a custom handleTriggerClick function, but couldn't figure out how to detect the source of the event and how to force the component to open/close.

How can I achieve this?

Trigger contains links

Hi,

I have the situation where the trigger is a react component and contains itself an <a href=.... /> link. Unfortunately the link is not working anymore since it is becoming also part of the trigger. Do you have a solution for that?

Thank you
D063520

overflowWhenOpen does not seem to work

Using v.1.2.1

<Collapsible
  easing="none"
  overflowWhenOpen="visible"
>

Results in:

<div class="Collapsible__contentOuter" style="height: 134px; overflow: hidden;">
  <div class="Collapsible__contentInner"></div>
</div>

Null values passed to className prop will render the string "null"

Code like this:

       const specialClass = somevar ? 'special-style' : null;

        return (
            <Collapsible
                classParentString="dbc-split-nav-item"
                className={specialClass}
            >
               Hello there.
            </Collapsible>
       );

winds up applying the class "null" when someVar is false. This is not idiomatic in React, where null values are generally ignored. I discovered this by accident when browsing the inspector. No harm done, but very strange :) One workaround is to set the class to an empty string, but that's a bit weird in this context.

Thanks for a helpful package.

Auto-collapse

In the API I can't find a functionality (maybe a Boolean property) to force collapse siblings of Collapsibles. I would like to have only one collapsible open at a time.
P.S. thanks for the good work

Only have one collapsible component open at a time

Is it possible to have only one collapsible element open at one time?

So for example if one component is open, and a user clicks on another trigger it animates that component open and closes all others?

Make it possible to override state classes

The state classes (.is-closed, is-open, .is-disabled) are not overridable.

I'm working on a project which uses CSS Modules and I'm trying to style a child element of the trigger element depending on the open / closed state.

I don't think that this is possible with the current implementation without also storing the state in a wrapper component (and using that to set a class on the child element).

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.