1 line
6.4 KiB
Plaintext
1 line
6.4 KiB
Plaintext
|
|
{"version":3,"sources":["../src/collapse.tsx"],"sourcesContent":["import { cx, warn } from \"@chakra-ui/shared-utils\"\nimport {\n AnimatePresence,\n HTMLMotionProps,\n motion,\n Variants as _Variants,\n} from \"framer-motion\"\nimport { forwardRef, useEffect, useState } from \"react\"\nimport {\n TRANSITION_EASINGS,\n Variants,\n withDelay,\n WithTransitionConfig,\n} from \"./transition-utils\"\n\nconst isNumeric = (value?: string | number) =>\n value != null && parseInt(value.toString(), 10) > 0\n\nexport interface CollapseOptions {\n /**\n * If `true`, the opacity of the content will be animated\n * @default true\n */\n animateOpacity?: boolean\n /**\n * The height you want the content in its collapsed state.\n * @default 0\n */\n startingHeight?: number | string\n /**\n * The height you want the content in its expanded state.\n * @default \"auto\"\n */\n endingHeight?: number | string\n}\n\nconst defaultTransitions = {\n exit: {\n height: { duration: 0.2, ease: TRANSITION_EASINGS.ease },\n opacity: { duration: 0.3, ease: TRANSITION_EASINGS.ease },\n },\n enter: {\n height: { duration: 0.3, ease: TRANSITION_EASINGS.ease },\n opacity: { duration: 0.4, ease: TRANSITION_EASINGS.ease },\n },\n}\n\nconst variants: Variants<CollapseOptions> = {\n exit: ({\n animateOpacity,\n startingHeight,\n transition,\n transitionEnd,\n delay,\n }) => ({\n ...(animateOpacity && { opacity: isNumeric(startingHeight) ? 1 : 0 }),\n height: startingHeight,\n transitionEnd: transitionEnd?.exit,\n transition:\n transition?.exit ?? withDelay.exit(defaultTransitions.exit, delay),\n }),\n enter: ({\n animateOpacity,\n endingHeight,\n transition,\n transitionEnd,\n delay,\n }) => ({\n ...(animateOpacity && { opacity: 1 }),\n height: endingHeight,\n transitionEnd: transitionEnd?.enter,\n transition:\n transition?.enter ?? withDelay.enter(defaultTransitions.enter, delay),\n }),\n}\n\nexport type ICollapse = CollapseProps\n\nexport interface CollapseProps\n extends WithTransitionConfig<HTMLMotionProps<\"div\">>,\n CollapseOptions {}\n\nexport const Collapse = forwardRef<HTMLDivElement, CollapseProps>(\n (props, ref) => {\n const {\n in: isOpen,\n unmountOnExit,\n animateOpacity = true,\n startingHeight = 0,\n endingHeight = \"auto\",\n style,\n className,\n transition,\n transitionEnd,\n ...rest\n } = props\n\n const [mounted, setMounted] = useState(false)\n useEffect(() => {\n const timeout = setTimeout(() => {\n setMounted(true)\n })\n return () => clearTimeout(timeout)\n }, [])\n\n /**\n * Warn 🚨: `startingHeight` and `unmountOnExit` are mutually exclusive\n *\n * If you specify a starting height, the collapsed needs to be mounted\n * for the height to take effect.\n */\n warn({\n condition: Number(startingHeight) > 0 && !!unmountOnExit,\n message: `startingHeight and unmountOnExit are mutually exclusive. You can't use them together`,\n })\n\n const hasStartingHeight = parseFloat(startingHeight.toString()) > 0\n\n const custom = {\n startingHeight,\n endingHeight,\n animateOpacity,\n transition: !mounted ? { enter: { duration: 0 } } : transition,\n transitionEnd: {\n enter: transitionEnd?.enter,\n exit: unmountOnExit\n ? transitionEnd?.exit\n : {\n ...transitionEnd?.exit,\n display: hasStartingHeight ? \"block\" : \"none\",\n },\n },\n }\n\n const show = unmountOnExit ? isOpen : true\n const animate = isOpen || unmountOnExit ? \"enter\" : \"exit\"\n\n return (\n <AnimatePresence initial={false} custom={custom}>\n {show && (\n <motion.div\n ref={ref}\n {...rest}\n className={cx(\"chakra-collapse\", className)}\n style={{\n overflow: \"hidden\",\n display: \"block\",\n ...style,\n
|