react-collapsible
Advanced tools
Comparing version 2.8.1 to 2.8.2
@@ -10,3 +10,3 @@ // Tests for Collapsible. | ||
const dummyEvent = { preventDefault: () => {}}; | ||
const dummyEvent = { preventDefault: () => {} }; | ||
@@ -16,9 +16,9 @@ class CollapsibleStateContainer extends React.Component { | ||
super(props); | ||
this.state = {open: !this.props.changeOpenTo}; | ||
this.state = { open: !this.props.changeOpenTo }; | ||
} | ||
componentDidMount(){ | ||
this.setState({open: this.props.changeOpenTo}); | ||
componentDidMount() { | ||
this.setState({ open: this.props.changeOpenTo }); | ||
} | ||
render() { | ||
return <Collapsible {...this.props} open={this.state.open}/>; | ||
return <Collapsible {...this.props} open={this.state.open} />; | ||
} | ||
@@ -34,4 +34,4 @@ } | ||
it('renders Collapsible with trigger text.', () => { | ||
const wrapper = shallow(<Collapsible trigger='Hello World'/> ) | ||
expect(wrapper.find('span').text()).toEqual('Hello World') | ||
const wrapper = shallow(<Collapsible trigger="Hello World" />); | ||
expect(wrapper.find('span').text()).toEqual('Hello World'); | ||
}); | ||
@@ -41,3 +41,5 @@ | ||
const mockOnOpening = jest.fn(); | ||
const collapsible = shallow(<Collapsible trigger='Hello World' onOpening={mockOnOpening}/> ); | ||
const collapsible = mount( | ||
<Collapsible trigger="Hello World" onOpening={mockOnOpening} /> | ||
); | ||
const trigger = collapsible.find('.Collapsible__trigger'); | ||
@@ -52,3 +54,5 @@ | ||
const mockOnClosing = jest.fn(); | ||
const collapsible = mount(<Collapsible open trigger='Hello World' onClosing={mockOnClosing}/> ); | ||
const collapsible = mount( | ||
<Collapsible open trigger="Hello World" onClosing={mockOnClosing} /> | ||
); | ||
const trigger = collapsible.find('.Collapsible__trigger'); | ||
@@ -63,5 +67,9 @@ | ||
const mockOnOpen = jest.fn(); | ||
const collapsible = shallow(<Collapsible open trigger='Hello World' onOpen={mockOnOpen}>Some Content</Collapsible> ); | ||
const collapsible = shallow( | ||
<Collapsible open trigger="Hello World" onOpen={mockOnOpen}> | ||
Some Content | ||
</Collapsible> | ||
); | ||
const outer = collapsible.find('.Collapsible__contentOuter'); | ||
expect(outer).toHaveLength(1); | ||
@@ -74,5 +82,9 @@ outer.simulate('transitionEnd', dummyEvent); | ||
const mockOnClose = jest.fn(); | ||
const collapsible = shallow(<Collapsible trigger='Hello World' onClose={mockOnClose}>Some Content</Collapsible> ); | ||
const collapsible = shallow( | ||
<Collapsible trigger="Hello World" onClose={mockOnClose}> | ||
Some Content | ||
</Collapsible> | ||
); | ||
const outer = collapsible.find('.Collapsible__contentOuter'); | ||
expect(outer).toHaveLength(1); | ||
@@ -85,3 +97,8 @@ outer.simulate('transitionEnd', dummyEvent); | ||
const mockHandleTriggerClick = jest.fn(); | ||
const collapsible = shallow(<Collapsible handleTriggerClick={mockHandleTriggerClick} trigger="Hello world" />); | ||
const collapsible = shallow( | ||
<Collapsible | ||
handleTriggerClick={mockHandleTriggerClick} | ||
trigger="Hello world" | ||
/> | ||
); | ||
const trigger = collapsible.find('.Collapsible__trigger'); | ||
@@ -92,10 +109,15 @@ | ||
expect(mockHandleTriggerClick.mock.calls).toHaveLength(1); | ||
}) | ||
}); | ||
describe('onTriggerOpening prop', () => { | ||
it('is called when a closed Collapsible is triggered', () => { | ||
const mockOnTriggerOpening = jest.fn(); | ||
const collapsible = mount(<Collapsible trigger='Hello World' onTriggerOpening={mockOnTriggerOpening} />); | ||
const collapsible = mount( | ||
<Collapsible | ||
trigger="Hello World" | ||
onTriggerOpening={mockOnTriggerOpening} | ||
/> | ||
); | ||
const trigger = collapsible.find('.Collapsible__trigger'); | ||
expect(trigger).toHaveLength(1); | ||
@@ -105,8 +127,14 @@ trigger.simulate('click', dummyEvent); | ||
}); | ||
it("is not called when a closed collapsible's open prop changes to true", () => { | ||
const mockOnTriggerOpening = jest.fn(); | ||
const collapsible = mount(<CollapsibleStateContainer changeOpenTo={true} trigger='Hello World' onTriggerOpening={mockOnTriggerOpening} />); | ||
const collapsible = mount( | ||
<CollapsibleStateContainer | ||
changeOpenTo={true} | ||
trigger="Hello World" | ||
onTriggerOpening={mockOnTriggerOpening} | ||
/> | ||
); | ||
const trigger = collapsible.find('.Collapsible__trigger'); | ||
expect(trigger).toHaveLength(1); | ||
@@ -116,9 +144,15 @@ expect(mockOnTriggerOpening.mock.calls).toHaveLength(0); | ||
}); | ||
describe('onTriggerClosing prop', () => { | ||
it('is called when an open Collapsible is triggered', () => { | ||
const mockOnTriggerClosing = jest.fn(); | ||
const collapsible = mount(<Collapsible open trigger='Hello World' onTriggerClosing={mockOnTriggerClosing} />); | ||
const collapsible = mount( | ||
<Collapsible | ||
open | ||
trigger="Hello World" | ||
onTriggerClosing={mockOnTriggerClosing} | ||
/> | ||
); | ||
const trigger = collapsible.find('.Collapsible__trigger'); | ||
expect(trigger).toHaveLength(1); | ||
@@ -128,8 +162,14 @@ trigger.simulate('click', dummyEvent); | ||
}); | ||
it("is not called when an open collapsible's open prop changes to false", () => { | ||
const mockOnTriggerClosing = jest.fn(); | ||
const collapsible = mount(<CollapsibleStateContainer changeOpenTo={false} trigger='Hello World' onTriggerClosing={mockOnTriggerClosing} />); | ||
const collapsible = mount( | ||
<CollapsibleStateContainer | ||
changeOpenTo={false} | ||
trigger="Hello World" | ||
onTriggerClosing={mockOnTriggerClosing} | ||
/> | ||
); | ||
const trigger = collapsible.find('.Collapsible__trigger'); | ||
expect(trigger).toHaveLength(1); | ||
@@ -139,2 +179,37 @@ expect(mockOnTriggerClosing.mock.calls).toHaveLength(0); | ||
}); | ||
}) | ||
describe('Zero Height Collapsibles', () => { | ||
it('opens correctly even if height is 0', () => { | ||
const wrapper = mount(<Collapsible />); | ||
expect(wrapper.state().height).toBe(0); | ||
expect(wrapper.state().isClosed).toBe(true); | ||
const trigger = wrapper.find('.Collapsible__trigger').simulate('click'); | ||
expect(wrapper.state().isClosed).toBe(false); | ||
}); | ||
it('closes correctly even if height is 0', () => { | ||
jest.useFakeTimers(); | ||
const mockFn = jest.fn(); | ||
const wrapper = mount( | ||
<Collapsible open={true} handleTriggerClick={mockFn} /> | ||
); | ||
expect(wrapper.state().height).toBe('auto'); // defaults to auto when open | ||
expect(wrapper.state().isClosed).toBe(false); | ||
wrapper.find('.Collapsible__trigger').simulate('click'); | ||
expect(mockFn.mock.calls).toHaveLength(1); | ||
wrapper.setProps({ open: false }); | ||
jest.runAllTimers(); | ||
expect(wrapper.state().isClosed).toBe(true); | ||
expect(wrapper.props().open).toBe(false); | ||
}); | ||
}); | ||
}); |
{ | ||
"name": "react-collapsible", | ||
"version": "2.8.1", | ||
"version": "2.8.2", | ||
"description": "React component to wrap content in Collapsible element with trigger to open and close.", | ||
@@ -12,3 +12,3 @@ "keywords": [ | ||
], | ||
"main": "dist/Collapsible.js", | ||
"main": "dist/index.js", | ||
"types": "./index.d.ts", | ||
@@ -22,23 +22,16 @@ "author": "Glenn Flanagan <glenn@arctictiger.co.uk>", | ||
"devDependencies": { | ||
"autoprefixer": "^7.1.2", | ||
"babel": "^5.6.23", | ||
"babel-cli": "^6.11.4", | ||
"babel-core": "^6.24.1", | ||
"babel-loader": "^7.0.0", | ||
"babel-preset-es2015": "^6.13.2", | ||
"@babel/core": "^7.11.4", | ||
"@babel/plugin-proposal-class-properties": "^7.10.4", | ||
"@babel/preset-env": "^7.11.0", | ||
"@babel/preset-react": "^7.10.4", | ||
"babel-loader": "^8.1.0", | ||
"babel-preset-react": "^6.11.1", | ||
"css-loader": "^3.2.0", | ||
"enzyme": "^3.3.0", | ||
"enzyme-adapter-react-16": "^1.1.1", | ||
"jest": "^26.0.1", | ||
"mini-css-extract-plugin": "^0.8.0", | ||
"node-sass": "^4.14.1", | ||
"postcss-loader": "^3.0.0", | ||
"prop-types": "^15.6.1", | ||
"react": "^16.3.1", | ||
"react-dom": "^16.3.1", | ||
"sass-loader": "^8.0.0", | ||
"webpack": "^4.43.0", | ||
"webpack-cli": "^3.3.10", | ||
"webpack-dev-server": "^3.11.0" | ||
"react": "^16.13.1", | ||
"react-dom": "^16.13.1", | ||
"webpack": "^4.44.1", | ||
"webpack-cli": "^3.3.12" | ||
}, | ||
@@ -53,5 +46,4 @@ "repository": { | ||
"scripts": { | ||
"build": "babel src/Collapsible.js > dist/Collapsible.js", | ||
"build": "webpack", | ||
"prepare": "npm run build", | ||
"example": "node_modules/.bin/webpack-dev-server", | ||
"test": "jest" | ||
@@ -58,0 +50,0 @@ }, |
161
README.md
@@ -13,6 +13,8 @@ [![Npm Version](https://img.shields.io/npm/v/react-collapsible.svg?style=flat-square)](https://www.npmjs.com/package/react-collapsible) [![License](https://img.shields.io/npm/l/react-collapsible.svg?style=flat-square)](https://github.com/glennflanagan/react-collapsible/blob/develop/LICENSE.md) [![Downloads Per Week](https://img.shields.io/npm/dw/react-collapsible.svg?style=flat-square)](https://npmcharts.com/compare/react-collapsible) | ||
![Browserstack Logo](example/img/browserstack-logo.png "Browserstack") | ||
![Browserstack Logo](example/img/browserstack-logo.png 'Browserstack') | ||
--- | ||
## 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. | ||
@@ -23,35 +25,34 @@ | ||
## Installation | ||
Install via npm or yarn | ||
``` | ||
```bash | ||
npm install react-collapsible --save | ||
yarn add react-collapsible | ||
``` | ||
Alternatively just download the `Collapsible.js` file form the `src` folder and include it in your project in your chosen way. | ||
## Usage | ||
## 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. | ||
### ES6 | ||
```javascript | ||
import React from 'react'; | ||
import Collapsible from 'react-collapsible'; | ||
var App = React.createClass({ | ||
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> | ||
); | ||
}; | ||
render: function() { | ||
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; | ||
@@ -64,103 +65,137 @@ ``` | ||
## Properties *(Options)* | ||
## Properties _(Options)_ | ||
### **contentContainerTagName** | *string* | default: `div` | ||
### **contentContainerTagName** | _string_ | default: `div` | ||
Tag Name for the Collapsible Root Element. | ||
### **containerElementProps** | *object* | ||
### **containerElementProps** | _object_ | ||
Pass props (or attributes) to the top div element. Useful for inserting `id`. | ||
### **trigger** | *string* or *React Element* | **required** | ||
### **trigger** | _string_ or _React Element_ | **required** | ||
The text or element to appear in the trigger link. | ||
### **triggerTagName** | *string* | default: span | ||
### **triggerTagName** | _string_ | default: span | ||
The tag name of the element wrapping the trigger text or element. | ||
### **triggerStyle** | *object* | default: null | ||
### **triggerStyle** | _object_ | default: null | ||
Adds a style attribute to the trigger. | ||
### **triggerWhenOpen** | *string* or *React Element* | ||
### **triggerWhenOpen** | _string_ or _React Element_ | ||
Optional trigger text or element to change to when the Collapsible is open. | ||
### **triggerDisabled** | *boolean* | default: false | ||
### **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* | ||
### **triggerElementProps** | _object_ | ||
Pass props (or attributes) to the trigger wrapping element. Useful for inserting `role` when using `tabIndex`. | ||
### **transitionTime** | *number* | default: 400 | ||
### **transitionTime** | _number_ | default: 400 | ||
The number of milliseconds for the open/close transition to take. | ||
### **transitionCloseTime** | *number* | default: null | ||
### **transitionCloseTime** | _number_ | default: null | ||
The number of milliseconds for the close transition to take. | ||
### **easing** | *string* | default: 'linear' | ||
### **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](https://developer.mozilla.org/en/docs/Web/CSS/transition-timing-function). | ||
### **open** | *bool* | default: false | ||
### **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* | ||
### **accordionPosition** | _string_ | ||
Unique key used to identify the `Collapse` instance when used in an accordion. | ||
### **handleTriggerClick** | *function* | ||
### **handleTriggerClick** | _function_ | ||
Define this to override the click handler for the trigger link. Takes one parameter, which is `props.accordionPosition`. | ||
### **onOpen** | *function* | ||
### **onOpen** | _function_ | ||
Is called when the Collapsible has opened. | ||
### **onClose** | *function* | ||
### **onClose** | _function_ | ||
Is called when the Collapsible has closed. | ||
### **onOpening** | *function* | ||
### **onOpening** | _function_ | ||
Is called when the Collapsible is opening. | ||
### **onClosing** | *function* | ||
### **onClosing** | _function_ | ||
Is called when the Collapsible is closing. | ||
### **onTriggerOpening** | *function* | ||
### **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* | ||
### **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 | ||
### **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' | ||
### **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 | ||
### **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 | ||
### **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 | ||
### **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 | ||
### **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* | ||
### **className** | _string_ | ||
`.Collapsible` element (root) when closed | ||
### **openedClassName** | *string* | ||
### **openedClassName** | _string_ | ||
`.Collapsible` element (root) when open | ||
### **triggerClassName** | *string* | ||
### **triggerClassName** | _string_ | ||
`.Collapsible__trigger` element (root) when closed | ||
### **triggerOpenedClassName** | *string* | ||
### **triggerOpenedClassName** | _string_ | ||
`.Collapsible__trigger` element (root) when open | ||
### **contentOuterClassName** | *string* | ||
### **contentOuterClassName** | _string_ | ||
`.Collapsible__contentOuter` element | ||
### **contentInnerClassName** | *string* | ||
### **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. | ||
@@ -170,11 +205,13 @@ | ||
The CSS class names follow a [type of BEM pattern](http://getbem.com/introduction/) of CSS naming. Below is a list of the CSS classes available on the component. | ||
The CSS class names follow a [type of BEM pattern](http://getbem.com/introduction/) of CSS naming. Below is a list of the CSS classes available on the component. | ||
### `.Collapsible` | ||
### `.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 | ||
@@ -185,5 +222,7 @@ - `is-open` | Open setState | ||
### `.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. | ||
@@ -194,10 +233,10 @@ | ||
## Example | ||
An example of the component in action is available in the example folder. To see it in action you can run | ||
```bash | ||
$ npm i | ||
$ npm run 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 the webpack build and open the example. | ||
This will run a [parceljs](https://parceljs.org) app. | ||
@@ -210,4 +249,4 @@ ## Issues | ||
## Licence | ||
## Licence | ||
React Responsive Collapsible Section Component is [MIT licensed](LICENSE.md) |
import React, { Component } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import setInTransition from './setInTransition'; | ||
class Collapsible extends Component { | ||
constructor(props) { | ||
super(props) | ||
super(props); | ||
this.timeout = undefined; | ||
// Bind class methods | ||
this.handleTriggerClick = this.handleTriggerClick.bind(this); | ||
this.handleTransitionEnd = this.handleTransitionEnd.bind(this); | ||
this.continueOpenCollapsible = this.continueOpenCollapsible.bind(this); | ||
this.setInnerRef = this.setInnerRef.bind(this); | ||
// Defaults the dropdown to be closed | ||
@@ -26,3 +22,3 @@ if (props.open) { | ||
inTransition: false, | ||
} | ||
}; | ||
} else { | ||
@@ -37,3 +33,3 @@ this.state = { | ||
inTransition: false, | ||
} | ||
}; | ||
} | ||
@@ -47,5 +43,9 @@ } | ||
if (prevState.height === 'auto' && this.state.shouldSwitchAutoOnNextCycle === true) { | ||
if ( | ||
(prevState.height === 'auto' || prevState.height === 0) && | ||
this.state.shouldSwitchAutoOnNextCycle === true | ||
) { | ||
window.clearTimeout(this.timeout); | ||
this.timeout = window.setTimeout(() => { // Set small timeout to ensure a true re-render | ||
this.timeout = window.setTimeout(() => { | ||
// Set small timeout to ensure a true re-render | ||
this.setState({ | ||
@@ -77,8 +77,13 @@ height: 0, | ||
closeCollapsible() { | ||
const { innerRef } = this; | ||
this.setState({ | ||
shouldSwitchAutoOnNextCycle: true, | ||
height: this.innerRef.scrollHeight, | ||
transition: `height ${this.props.transitionCloseTime ? | ||
this.props.transitionCloseTime : this.props.transitionTime}ms ${this.props.easing}`, | ||
inTransition: true, | ||
height: innerRef.scrollHeight, | ||
transition: `height ${ | ||
this.props.transitionCloseTime | ||
? this.props.transitionCloseTime | ||
: this.props.transitionTime | ||
}ms ${this.props.easing}`, | ||
inTransition: setInTransition(innerRef.scrollHeight), | ||
}); | ||
@@ -89,3 +94,3 @@ } | ||
this.setState({ | ||
inTransition: true, | ||
inTransition: setInTransition(this.innerRef.scrollHeight), | ||
shouldOpenOnNextCycle: true, | ||
@@ -95,16 +100,18 @@ }); | ||
continueOpenCollapsible() { | ||
continueOpenCollapsible = () => { | ||
const { innerRef } = this; | ||
this.setState({ | ||
height: this.innerRef.scrollHeight, | ||
height: innerRef.scrollHeight, | ||
transition: `height ${this.props.transitionTime}ms ${this.props.easing}`, | ||
isClosed: false, | ||
hasBeenOpened: true, | ||
inTransition: true, | ||
inTransition: setInTransition(innerRef.scrollHeight), | ||
shouldOpenOnNextCycle: false, | ||
}); | ||
} | ||
}; | ||
handleTriggerClick(event) { | ||
handleTriggerClick = (event) => { | ||
if (this.props.triggerDisabled || this.state.inTransition) { | ||
return | ||
return; | ||
} | ||
@@ -114,3 +121,2 @@ | ||
if (this.props.handleTriggerClick) { | ||
@@ -129,19 +135,26 @@ this.props.handleTriggerClick(this.props.accordionPosition); | ||
} | ||
} | ||
}; | ||
renderNonClickableTriggerElement() { | ||
if (this.props.triggerSibling && typeof this.props.triggerSibling === 'string') { | ||
if ( | ||
this.props.triggerSibling && | ||
typeof this.props.triggerSibling === 'string' | ||
) { | ||
return ( | ||
<span className={`${this.props.classParentString}__trigger-sibling`}>{this.props.triggerSibling}</span> | ||
) | ||
} else if (this.props.triggerSibling && typeof this.props.triggerSibling === 'function') { | ||
<span className={`${this.props.classParentString}__trigger-sibling`}> | ||
{this.props.triggerSibling} | ||
</span> | ||
); | ||
} else if ( | ||
this.props.triggerSibling && | ||
typeof this.props.triggerSibling === 'function' | ||
) { | ||
return this.props.triggerSibling(); | ||
} else if (this.props.triggerSibling) { | ||
return <this.props.triggerSibling /> | ||
return <this.props.triggerSibling />; | ||
} | ||
return null; | ||
} | ||
handleTransitionEnd(e) { | ||
handleTransitionEnd = (e) => { | ||
// only handle transitions that origin from the container of this component | ||
@@ -153,3 +166,7 @@ if (e.target !== this.innerRef) { | ||
if (!this.state.isClosed) { | ||
this.setState({ height: 'auto', overflow: this.props.overflowWhenOpen, inTransition: false }); | ||
this.setState({ | ||
height: 'auto', | ||
overflow: this.props.overflowWhenOpen, | ||
inTransition: false, | ||
}); | ||
this.props.onOpen(); | ||
@@ -160,7 +177,5 @@ } else { | ||
} | ||
} | ||
}; | ||
setInnerRef(ref) { | ||
this.innerRef = ref | ||
} | ||
setInnerRef = (ref) => (this.innerRef = ref); | ||
@@ -174,3 +189,3 @@ render() { | ||
overflow: this.state.overflow, | ||
} | ||
}; | ||
@@ -181,5 +196,6 @@ var openClass = this.state.isClosed ? 'is-closed' : 'is-open'; | ||
//If user wants different text when tray is open | ||
var trigger = (this.state.isClosed === false) && (this.props.triggerWhenOpen !== undefined) | ||
? this.props.triggerWhenOpen | ||
: this.props.trigger; | ||
var trigger = | ||
this.state.isClosed === false && this.props.triggerWhenOpen !== undefined | ||
? this.props.triggerWhenOpen | ||
: this.props.trigger; | ||
@@ -192,14 +208,21 @@ const ContentContainerElement = this.props.contentContainerTagName; | ||
// Don't render children until the first opening of the Collapsible if lazy rendering is enabled | ||
var children = this.props.lazyRender | ||
&& !this.state.hasBeenOpened | ||
&& this.state.isClosed | ||
&& !this.state.inTransition ? null : this.props.children; | ||
var children = | ||
this.props.lazyRender && | ||
!this.state.hasBeenOpened && | ||
this.state.isClosed && | ||
!this.state.inTransition | ||
? null | ||
: this.props.children; | ||
// Construct CSS classes strings | ||
const triggerClassString = `${this.props.classParentString}__trigger ${openClass} ${disabledClass} ${ | ||
this.state.isClosed ? this.props.triggerClassName : this.props.triggerOpenedClassName | ||
}`; | ||
const triggerClassString = `${ | ||
this.props.classParentString | ||
}__trigger ${openClass} ${disabledClass} ${ | ||
this.state.isClosed | ||
? this.props.triggerClassName | ||
: this.props.triggerOpenedClassName | ||
}`; | ||
const parentClassString = `${this.props.classParentString} ${ | ||
this.state.isClosed ? this.props.className : this.props.openedClassName | ||
}`; | ||
}`; | ||
const outerClassString = `${this.props.classParentString}__contentOuter ${this.props.contentOuterClassName}`; | ||
@@ -209,3 +232,6 @@ const innerClassString = `${this.props.classParentString}__contentInner ${this.props.contentInnerClassName}`; | ||
return ( | ||
<ContentContainerElement className={parentClassString.trim()} {...this.props.containerElementProps} > | ||
<ContentContainerElement | ||
className={parentClassString.trim()} | ||
{...this.props.containerElementProps} | ||
> | ||
<TriggerElement | ||
@@ -217,3 +243,7 @@ className={triggerClassString.trim()} | ||
const { key } = event; | ||
if ((key === ' ' && this.props.triggerTagName.toLowerCase() !== 'button') || key === 'Enter') { | ||
if ( | ||
(key === ' ' && | ||
this.props.triggerTagName.toLowerCase() !== 'button') || | ||
key === 'Enter' | ||
) { | ||
this.handleTriggerClick(event); | ||
@@ -235,9 +265,9 @@ } | ||
ref={this.setInnerRef} | ||
hidden={this.props.contentHiddenWhenClosed && this.state.isClosed && !this.state.inTransition} | ||
hidden={ | ||
this.props.contentHiddenWhenClosed && | ||
this.state.isClosed && | ||
!this.state.inTransition | ||
} | ||
> | ||
<div | ||
className={innerClassString.trim()} | ||
> | ||
{children} | ||
</div> | ||
<div className={innerClassString.trim()}>{children}</div> | ||
</div> | ||
@@ -272,10 +302,4 @@ </ContentContainerElement> | ||
onTriggerClosing: PropTypes.func, | ||
trigger: PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.element | ||
]), | ||
triggerWhenOpen: PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.element | ||
]), | ||
trigger: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), | ||
triggerWhenOpen: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), | ||
triggerDisabled: PropTypes.bool, | ||
@@ -293,9 +317,6 @@ lazyRender: PropTypes.bool, | ||
contentHiddenWhenClosed: PropTypes.bool, | ||
triggerSibling: PropTypes.oneOfType([ | ||
PropTypes.element, | ||
PropTypes.func, | ||
]), | ||
triggerSibling: PropTypes.oneOfType([PropTypes.element, PropTypes.func]), | ||
tabIndex: PropTypes.number, | ||
contentContainerTagName: PropTypes.string, | ||
} | ||
}; | ||
@@ -321,8 +342,8 @@ Collapsible.defaultProps = { | ||
triggerSibling: null, | ||
onOpen: () => { }, | ||
onClose: () => { }, | ||
onOpening: () => { }, | ||
onClosing: () => { }, | ||
onTriggerOpening: () => { }, | ||
onTriggerClosing: () => { }, | ||
onOpen: () => {}, | ||
onClose: () => {}, | ||
onOpening: () => {}, | ||
onClosing: () => {}, | ||
onTriggerOpening: () => {}, | ||
onTriggerClosing: () => {}, | ||
tabIndex: null, | ||
@@ -329,0 +350,0 @@ contentContainerTagName: 'div', |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
14
14
246
0
41176
545
1
2
1