UNPKG

3.32 kBJavaScriptView Raw
1import classNames from 'classnames';
2import css from 'dom-helpers/css';
3import React, { useMemo } from 'react';
4import { ENTERED, ENTERING, EXITED, EXITING } from 'react-transition-group/Transition';
5import transitionEndListener from './transitionEndListener';
6import createChainedFunction from './createChainedFunction';
7import triggerBrowserReflow from './triggerBrowserReflow';
8import TransitionWrapper from './TransitionWrapper';
9import { jsx as _jsx } from "react/jsx-runtime";
10const MARGINS = {
11 height: ['marginTop', 'marginBottom'],
12 width: ['marginLeft', 'marginRight']
13};
14function getDefaultDimensionValue(dimension, elem) {
15 const offset = `offset${dimension[0].toUpperCase()}${dimension.slice(1)}`;
16 const value = elem[offset];
17 const margins = MARGINS[dimension];
18 return value +
19 // @ts-ignore
20 parseInt(css(elem, margins[0]), 10) +
21 // @ts-ignore
22 parseInt(css(elem, margins[1]), 10);
23}
24const collapseStyles = {
25 [EXITED]: 'collapse',
26 [EXITING]: 'collapsing',
27 [ENTERING]: 'collapsing',
28 [ENTERED]: 'collapse show'
29};
30const Collapse = /*#__PURE__*/React.forwardRef(({
31 onEnter,
32 onEntering,
33 onEntered,
34 onExit,
35 onExiting,
36 className,
37 children,
38 dimension = 'height',
39 in: inProp = false,
40 timeout = 300,
41 mountOnEnter = false,
42 unmountOnExit = false,
43 appear = false,
44 getDimensionValue = getDefaultDimensionValue,
45 ...props
46}, ref) => {
47 /* Compute dimension */
48 const computedDimension = typeof dimension === 'function' ? dimension() : dimension;
49
50 /* -- Expanding -- */
51 const handleEnter = useMemo(() => createChainedFunction(elem => {
52 elem.style[computedDimension] = '0';
53 }, onEnter), [computedDimension, onEnter]);
54 const handleEntering = useMemo(() => createChainedFunction(elem => {
55 const scroll = `scroll${computedDimension[0].toUpperCase()}${computedDimension.slice(1)}`;
56 elem.style[computedDimension] = `${elem[scroll]}px`;
57 }, onEntering), [computedDimension, onEntering]);
58 const handleEntered = useMemo(() => createChainedFunction(elem => {
59 elem.style[computedDimension] = null;
60 }, onEntered), [computedDimension, onEntered]);
61
62 /* -- Collapsing -- */
63 const handleExit = useMemo(() => createChainedFunction(elem => {
64 elem.style[computedDimension] = `${getDimensionValue(computedDimension, elem)}px`;
65 triggerBrowserReflow(elem);
66 }, onExit), [onExit, getDimensionValue, computedDimension]);
67 const handleExiting = useMemo(() => createChainedFunction(elem => {
68 elem.style[computedDimension] = null;
69 }, onExiting), [computedDimension, onExiting]);
70 return /*#__PURE__*/_jsx(TransitionWrapper, {
71 ref: ref,
72 addEndListener: transitionEndListener,
73 ...props,
74 "aria-expanded": props.role ? inProp : null,
75 onEnter: handleEnter,
76 onEntering: handleEntering,
77 onEntered: handleEntered,
78 onExit: handleExit,
79 onExiting: handleExiting,
80 childRef: children.ref,
81 in: inProp,
82 timeout: timeout,
83 mountOnEnter: mountOnEnter,
84 unmountOnExit: unmountOnExit,
85 appear: appear,
86 children: (state, innerProps) => /*#__PURE__*/React.cloneElement(children, {
87 ...innerProps,
88 className: classNames(className, children.props.className, collapseStyles[state], computedDimension === 'width' && 'collapse-horizontal')
89 })
90 });
91});
92
93// @ts-ignore
94
95export default Collapse;
\No newline at end of file