UNPKG

@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.

190 lines (163 loc) 7.33 kB
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } import * as React from "react"; import styled from "styled-components"; import defaultTokens from "../defaultTokens"; import Close from "../icons/Close"; import ButtonLink from "../ButtonLink"; import CardSection, { StyledCardSection } from "./CardSection"; import CardHeader, { StyledCardHeader } from "./CardHeader"; import Loading, { StyledLoading } from "../Loading"; import getSpacingToken from "../common/getSpacingToken"; const getBorder = ({ theme }) => `${theme.orbit.borderWidthCard} ${theme.orbit.borderStyleCard} ${theme.orbit.borderColorCard}`; const getBorderRadius = ({ theme }) => theme.orbit.borderRadiusNormal; // Logic of borders radius const StyledChildWrapper = styled.div.withConfig({ displayName: "Card__StyledChildWrapper", componentId: "ff0z2v-0" })(["", ",", ",", "{border-top-left-radius:", ";border-top-right-radius:", ";border-bottom-left-radius:", ";border-bottom-right-radius:", ";border-left:", ";border-right:", ";border-bottom:", ";background:", ";}+ div ", "{border-top:", ";}"], StyledCardSection, StyledCardHeader, StyledLoading, ({ roundedTopBorders }) => roundedTopBorders && getBorderRadius, ({ roundedTopBorders }) => roundedTopBorders && getBorderRadius, ({ roundedBottomBorders }) => roundedBottomBorders && getBorderRadius, ({ roundedBottomBorders }) => roundedBottomBorders && getBorderRadius, getBorder, getBorder, getBorder, ({ theme }) => theme.orbit.backgroundCard, StyledCardSection, ({ expanded }) => expanded && getBorder); StyledChildWrapper.defaultProps = { theme: defaultTokens }; const StyledCard = styled.div.withConfig({ displayName: "Card__StyledCard", componentId: "ff0z2v-1" })(["width:100%;height:100%;box-sizing:border-box;position:relative;margin-bottom:", ";", "{padding-right:", ";border-bottom:", ";}", "{&:first-of-type{", ",", ",", "{border-top:", ";border-top-left-radius:", ";border-top-right-radius:", ";}+ ", " ", "{padding-top:", ";}}&:last-of-type{", ",", "{border-bottom-left-radius:", ";border-bottom-right-radius:", ";}}}"], getSpacingToken, StyledCardHeader, ({ theme, closable }) => closable && theme.orbit.spaceLarge, ({ hasAdjustedHeader }) => hasAdjustedHeader && 0, StyledChildWrapper, StyledCardHeader, StyledCardSection, StyledLoading, getBorder, getBorderRadius, getBorderRadius, StyledChildWrapper, StyledCardSection, ({ hasAdjustedHeader }) => hasAdjustedHeader && 0, StyledCardHeader, StyledCardSection, getBorderRadius, getBorderRadius); StyledCard.defaultProps = { theme: defaultTokens }; const CloseContainer = styled.div.withConfig({ displayName: "Card__CloseContainer", componentId: "ff0z2v-2" })(["position:absolute;top:0;right:0;z-index:1;"]); // Logic of spacing and animation in expandable Card const StyledExpandableSectionWrapper = styled.div.withConfig({ displayName: "Card__StyledExpandableSectionWrapper", componentId: "ff0z2v-3" })(["margin:", ";transition:margin ", " ease-in-out;box-shadow:", ";", "{border-top:", ";}"], ({ theme, expanded }) => expanded && `${theme.orbit.spaceXSmall} 0`, ({ theme }) => theme.orbit.durationFast, ({ expanded }) => expanded && `0 4px 12px 0 rgba(23, 27, 30, 0.1)`, StyledCardSection, ({ expanded }) => expanded && getBorder); StyledExpandableSectionWrapper.defaultProps = { theme: defaultTokens }; class Card extends React.Component { constructor(...args) { super(...args); _defineProperty(this, "state", { expandedSections: [] }); _defineProperty(this, "getRoundedBorders", index => { const { expandedSections } = this.state; const topBorder = expandedSections.indexOf(index - 1) !== -1 || expandedSections.indexOf(index) !== -1; const bottomBorder = expandedSections.indexOf(index + 1) !== -1 || expandedSections.indexOf(index) !== -1; return { top: topBorder, bottom: bottomBorder }; }); _defineProperty(this, "getChildren", () => { // Loading Card Logic const children = React.Children.toArray(this.props.children); if (children[0] === undefined) { // Jest test return []; } if (children[0].type.name === Loading.name && !children[0].props.loading) { if (!Array.isArray(children[0].props.children) && children[0].props.children.type.toString() === React.Fragment.toString()) { return children[0].props.children.props.children; } return children[0].props.children; } return children; }); _defineProperty(this, "isExpandableCardSection", item => item.type.name === CardSection.name && item.props.expandable); _defineProperty(this, "isExpanded", index => this.state.expandedSections.indexOf(index) !== -1); _defineProperty(this, "handleToggleSection", index => { this.setState({ expandedSections: this.state.expandedSections.indexOf(index) === -1 ? [...this.state.expandedSections, index] : this.state.expandedSections.filter(value => value !== index) }); }); _defineProperty(this, "hasAdjustedHeader", () => { const children = this.getChildren(); // Check if first element is Header if (children[0] !== undefined && children[0].type.name !== CardHeader.name) { return false; } // Check if first section exists if (children[1] === undefined) { return false; } return !this.isExpandableCardSection(children[1]); }); _defineProperty(this, "renderSection", (section, index) => { const roundedBorders = this.getRoundedBorders(index); return React.createElement(StyledChildWrapper, { roundedTopBorders: roundedBorders.top, roundedBottomBorders: roundedBorders.bottom }, section); }); _defineProperty(this, "renderExpandableSection", (section, index) => { const isExpanded = this.isExpanded(index); const roundedBorders = this.getRoundedBorders(index); return React.createElement(StyledChildWrapper, { roundedTopBorders: roundedBorders.top, roundedBottomBorders: roundedBorders.bottom, expanded: isExpanded }, React.createElement(StyledExpandableSectionWrapper, { expanded: isExpanded }, React.cloneElement(section, { expanded: this.isExpanded(index), onClick: () => this.handleToggleSection(index) }))); }); } render() { const { closable, dataTest, spaceAfter, onClose } = this.props; const children = this.getChildren(); return React.createElement(StyledCard, { closable: closable, "data-test": dataTest, spaceAfter: spaceAfter, hasAdjustedHeader: this.hasAdjustedHeader() }, children && React.Children.map(children, (item, index) => this.isExpandableCardSection(item) ? this.renderExpandableSection(item, index) : this.renderSection(item, index)), closable && React.createElement(CloseContainer, null, React.createElement(ButtonLink, { type: "secondary", size: "small", icon: React.createElement(Close, null), onClick: onClose, transparent: true }))); } } export default Card;