@kiwicom/orbit-components
Version:
Orbit-components is a React component library which provides developers with the easiest possible way of building Kiwi.com’s products.
138 lines (134 loc) • 4.31 kB
JavaScript
import * as React from "react";
import styled, { css } from "styled-components";
import Heading from "../Heading";
import Stack from "../Stack";
import ButtonLink from "../ButtonLink";
import ChevronDown from "../icons/ChevronDown";
import Slide from "../utils/Slide";
import defaultTheme from "../defaultTheme";
import randomID from "../utils/randomID";
import useTranslate from "../hooks/useTranslate";
const AnimatedIcon = styled(ChevronDown).withConfig({
displayName: "Collapse__AnimatedIcon",
componentId: "x5d7nf-0"
})(["transition:transform ", " ease-in-out;", ";"], ({
theme
}) => theme.orbit.durationFast, ({
expanded
}) => expanded && css(["transform:rotate(180deg);"]));
AnimatedIcon.defaultProps = {
theme: defaultTheme
};
const StyledCollapse = styled.div.withConfig({
displayName: "Collapse__StyledCollapse",
componentId: "x5d7nf-1"
})(["width:100%;display:block;border-bottom:1px solid ", ";padding-bottom:", ";margin-bottom:", ";:last-child,:only-child{border:0;margin:0;}"], ({
theme
}) => theme.orbit.paletteCloudNormal, ({
theme
}) => theme.orbit.spaceMedium, ({
theme
}) => theme.orbit.spaceMedium);
StyledCollapse.defaultProps = {
theme: defaultTheme
};
const StyledCollapseLabel = styled.div.withConfig({
displayName: "Collapse__StyledCollapseLabel",
componentId: "x5d7nf-2"
})(["width:100%;display:block;cursor:pointer;"]);
const StyledCollapseChildren = styled.div.withConfig({
displayName: "Collapse__StyledCollapseChildren",
componentId: "x5d7nf-3"
})(["margin-top:", ";"], ({
theme
}) => theme.orbit.spaceXSmall);
StyledCollapseChildren.defaultProps = {
theme: defaultTheme
};
const StyledActionsWrapper = styled.div.withConfig({
displayName: "Collapse__StyledActionsWrapper",
componentId: "x5d7nf-4"
})(["display:flex;align-items:center;"]);
const Collapse = ({
initialExpanded = false,
expanded: expandedProp,
label,
children,
dataTest,
onClick,
actions
}) => {
const isControlledComponent = React.useMemo(() => expandedProp != null, [expandedProp]);
const [expandedState, setExpandedState] = React.useState(isControlledComponent ? expandedProp : initialExpanded);
const expanded = isControlledComponent ? expandedProp : expandedState;
const [contentHeight, setContentHeight] = React.useState(expanded ? null : 0);
const node = React.useRef(null);
const translate = useTranslate();
React.useEffect(() => {
const calculateHeight = () => {
if (node && node.current) {
const {
height
} = node.current.getBoundingClientRect();
setContentHeight(height);
}
};
calculateHeight();
window.addEventListener("resize", calculateHeight);
return () => {
window.removeEventListener("resize", calculateHeight);
};
}, []);
const slideID = React.useMemo(() => randomID("slideID"), []);
const labelID = React.useMemo(() => randomID("labelID"), []);
const handleClick = React.useCallback(event => {
if (!isControlledComponent) {
if (onClick) {
onClick(event, !expanded);
}
setExpandedState(!expanded);
} else if (onClick) {
onClick(event, !expanded);
}
}, [expanded, isControlledComponent, onClick]);
return React.createElement(StyledCollapse, {
"data-test": dataTest
}, React.createElement(StyledCollapseLabel, {
onClick: handleClick,
role: "button",
"aria-expanded": expanded,
"aria-controls": slideID,
id: labelID
}, React.createElement(Stack, {
justify: "between",
align: "center"
}, React.createElement(Heading, {
type: "title4",
element: "div"
}, label), React.createElement(Stack, {
inline: true,
grow: false,
align: "center",
spacing: "compact"
}, React.createElement(StyledActionsWrapper, {
onClick: ev => {
ev.stopPropagation();
}
}, actions), React.createElement(ButtonLink, {
iconLeft: React.createElement(AnimatedIcon, {
expanded: expanded
}),
transparent: true,
size: "small",
type: "secondary",
title: translate("drawer_hide")
})))), React.createElement(Slide, {
maxHeight: contentHeight,
expanded: expanded,
id: slideID,
ariaLabelledBy: labelID
}, React.createElement(StyledCollapseChildren, {
ref: node
}, children)));
};
export default Collapse;