@talend/react-bootstrap
Version:
Bootstrap 3 components built with React
183 lines (181 loc) • 6.35 kB
JavaScript
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
/* eslint-disable arrow-parens */
import classNames from 'classnames';
import css from 'dom-helpers/style';
import React from 'react';
import PropTypes from 'prop-types';
import Transition, { EXITED, ENTERED, ENTERING, EXITING } from 'react-transition-group/Transition';
import capitalize from './utils/capitalize';
import createChainedFunction from './utils/createChainedFunction';
import { jsx as _jsx } from "react/jsx-runtime";
const MARGINS = {
height: ['marginTop', 'marginBottom'],
width: ['marginLeft', 'marginRight']
};
// reading a dimension prop will cause the browser to recalculate,
// which will let our animations work
function triggerBrowserReflow(node) {
// eslint-disable-next-line mdx/no-unused-expressions
node.offsetHeight;
}
function getDimensionValue(dimension, elem) {
let value = elem[`offset${capitalize(dimension)}`];
let margins = MARGINS[dimension];
return value + parseInt(css(elem, margins[0]), 10) + parseInt(css(elem, margins[1]), 10);
}
const collapseStyles = {
[EXITED]: 'collapse',
[EXITING]: 'collapsing',
[ENTERING]: 'collapsing',
[ENTERED]: 'collapse in'
};
const propTypes = {
className: PropTypes.string,
children: PropTypes.node,
/**
* Show the component; triggers the expand or collapse animation
*/
in: PropTypes.bool,
/**
* Wait until the first "enter" transition to mount the component (add it to the DOM)
*/
mountOnEnter: PropTypes.bool,
/**
* Unmount the component (remove it from the DOM) when it is collapsed
*/
unmountOnExit: PropTypes.bool,
/**
* Run the expand animation when the component mounts, if it is initially
* shown
*/
appear: PropTypes.bool,
/**
* Duration of the collapse animation in milliseconds, to ensure that
* finishing callbacks are fired even if the original browser transition end
* events are canceled
*/
timeout: PropTypes.number,
/**
* Callback fired before the component expands
*/
onEnter: PropTypes.func,
/**
* Callback fired after the component starts to expand
*/
onEntering: PropTypes.func,
/**
* Callback fired after the component has expanded
*/
onEntered: PropTypes.func,
/**
* Callback fired before the component collapses
*/
onExit: PropTypes.func,
/**
* Callback fired after the component starts to collapse
*/
onExiting: PropTypes.func,
/**
* Callback fired after the component has collapsed
*/
onExited: PropTypes.func,
/**
* The dimension used when collapsing, or a function that returns the
* dimension
*
* _Note: Bootstrap only partially supports 'width'!
* You will need to supply your own CSS animation for the `.width` CSS class._
*/
dimension: PropTypes.oneOfType([PropTypes.oneOf(['height', 'width']), PropTypes.func]),
/**
* Function that returns the height or width of the animating DOM node
*
* Allows for providing some custom logic for how much the Collapse component
* should animate in its specified dimension. Called with the current
* dimension prop value and the DOM node.
*/
getDimensionValue: PropTypes.func,
/**
* ARIA role of collapsible element
*/
role: PropTypes.string
};
const defaultProps = {
in: false,
timeout: 300,
mountOnEnter: false,
unmountOnExit: false,
appear: false,
dimension: 'height',
getDimensionValue
};
class Collapse extends React.Component {
constructor(...args) {
super(...args);
/* -- Expanding -- */
_defineProperty(this, "handleEnter", elem => {
elem.style[this.getDimension()] = '0';
});
_defineProperty(this, "handleEntering", elem => {
const dimension = this.getDimension();
elem.style[dimension] = this._getScrollDimensionValue(elem, dimension);
});
_defineProperty(this, "handleEntered", elem => {
elem.style[this.getDimension()] = null;
});
/* -- Collapsing -- */
_defineProperty(this, "handleExit", elem => {
const dimension = this.getDimension();
elem.style[dimension] = `${this.props.getDimensionValue(dimension, elem)}px`;
triggerBrowserReflow(elem);
});
_defineProperty(this, "handleExiting", elem => {
elem.style[this.getDimension()] = '0';
});
}
getDimension() {
return typeof this.props.dimension === 'function' ? this.props.dimension() : this.props.dimension;
}
// for testing
_getScrollDimensionValue(elem, dimension) {
return `${elem[`scroll${capitalize(dimension)}`]}px`;
}
render() {
const {
onEnter,
onEntering,
onEntered,
onExit,
onExiting,
className,
children,
...props
} = this.props;
delete props.dimension;
delete props.getDimensionValue;
const handleEnter = createChainedFunction(this.handleEnter, onEnter);
const handleEntering = createChainedFunction(this.handleEntering, onEntering);
const handleEntered = createChainedFunction(this.handleEntered, onEntered);
const handleExit = createChainedFunction(this.handleExit, onExit);
const handleExiting = createChainedFunction(this.handleExiting, onExiting);
return /*#__PURE__*/_jsx(Transition, {
...props,
"aria-expanded": props.role ? props.in : null,
onEnter: handleEnter,
onEntering: handleEntering,
onEntered: handleEntered,
onExit: handleExit,
onExiting: handleExiting,
children: (state, innerProps) => /*#__PURE__*/React.cloneElement(children, {
...innerProps,
className: classNames(className, children.props.className, collapseStyles[state], this.getDimension() === 'width' && 'width')
})
});
}
}
Collapse.propTypes = propTypes;
Collapse.defaultProps = defaultProps;
export default Collapse;
//# sourceMappingURL=Collapse.js.map