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.

188 lines 7.71 kB
import * as React from "react"; import styled, { css } from "styled-components"; import HorizontalScroll from "../../../HorizontalScroll"; import Truncate from "../../../Truncate"; import { left, rtlSpacing } from "../../../utils/rtl"; import ChevronUp from "../../../icons/ChevronUp"; import ChevronDown from "../../../icons/ChevronDown"; import themeDefault from "../../../defaultTheme"; import Stack from "../../../Stack"; // TODO: remove after designers will resolve status colors // https://skypicker.slack.com/archives/GSGN9BN6Q/p1674568716519889 import TemporaryText from "../../ItineraryTemporaryText"; import Text from "../../../Text"; import Slide from "../../../utils/Slide"; import useBoundingRect from "../../../hooks/useBoundingRect"; import { useRandomIdSeed } from "../../../hooks/useRandomId"; import { usePart } from "../context"; import { useWidth } from "../../context"; import AirplaneDown from "../../../icons/AirplaneDown"; import ItineraryIcon from "../ItineraryIcon"; const StyledWrapper = styled.div.withConfig({ displayName: "ItinerarySegmentDetail__StyledWrapper", componentId: "sc-11uilyz-0" })(["width:100%;position:relative;padding:10px 0;box-sizing:border-box;"]); const StyledDetailsIcon = styled.div.withConfig({ displayName: "ItinerarySegmentDetail__StyledDetailsIcon", componentId: "sc-11uilyz-1" })(["background:transparent;z-index:1;"]); const StyledInnerWrapper = styled.div.withConfig({ displayName: "ItinerarySegmentDetail__StyledInnerWrapper", componentId: "sc-11uilyz-2" })(["", ""], ({ theme }) => css(["padding:", ";"], rtlSpacing(`0 ${theme.orbit.spaceSmall}`))); StyledInnerWrapper.defaultProps = { theme: themeDefault }; export const StyledSummary = styled.div.withConfig({ displayName: "ItinerarySegmentDetail__StyledSummary", componentId: "sc-11uilyz-3" })(["display:flex;align-items:center;width:100%;overflow:hidden;"]); StyledSummary.defaultProps = { theme: themeDefault }; const StyledDuration = styled.div.withConfig({ displayName: "ItinerarySegmentDetail__StyledDuration", componentId: "sc-11uilyz-4" })(["", ""], ({ $minWidth }) => css(["display:flex;justify-content:flex-end;min-width:", ";"], $minWidth && `${$minWidth}px`)); const StyledExpandable = styled.div.withConfig({ displayName: "ItinerarySegmentDetail__StyledExpandable", componentId: "sc-11uilyz-5" })(["", ""], ({ theme }) => css(["padding-top:", ";"], theme.orbit.spaceSmall)); StyledExpandable.defaultProps = { theme: themeDefault }; const StyledExpandableContent = styled.div.withConfig({ displayName: "ItinerarySegmentDetail__StyledExpandableContent", componentId: "sc-11uilyz-6" })(["", ""], ({ $offset, theme }) => css(["padding:0 ", ";position:relative;z-index:1;margin-", ":", "px;"], theme.orbit.spaceSmall, left, parseInt(theme.orbit.spaceXSmall, 10) + $offset)); const StyledHeadingOffset = styled.div.withConfig({ displayName: "ItinerarySegmentDetail__StyledHeadingOffset", componentId: "sc-11uilyz-7" })(["", ""], ({ theme }) => css(["margin-", ":", ";"], left, theme.orbit.spaceXLarge)); const StyledIcon = styled.div.withConfig({ displayName: "ItinerarySegmentDetail__StyledIcon", componentId: "sc-11uilyz-8" })(["", ""], ({ theme, isFirst, isLast }) => css(["display:flex;align-items:center;position:relative;box-sizing:border-box;padding:", ";z-index:3;svg{padding-top:", ";padding-bottom:", ";}&:after{content:\"\";box-sizing:border-box;position:absolute;width:100%;height:100%;left:0;border-left:1px solid ", ";border-right:1px solid ", ";z-index:-1;background:", ";", " ", "}"], theme.orbit.spaceXXSmall, isFirst && theme.orbit.spaceXXSmall, isLast && theme.orbit.spaceXXSmall, theme.orbit.paletteCloudNormalActive, theme.orbit.paletteCloudNormalActive, theme.orbit.paletteWhite, isFirst && css(["border:1px solid ", ";border-bottom:transparent;border-radius:", " ", " 0 0;"], theme.orbit.paletteCloudNormalActive, theme.orbit.spaceLarge, theme.orbit.spaceLarge), isLast && css(["border:1px solid ", ";border-top:transparent;border-radius:0 0 ", " ", ";"], theme.orbit.paletteCloudNormalActive, theme.orbit.spaceLarge, theme.orbit.spaceLarge))); StyledIcon.defaultProps = { theme: themeDefault }; StyledExpandableContent.defaultProps = { theme: themeDefault }; const ItinerarySegmentDetail = ({ duration, summary, content, icon = /*#__PURE__*/React.createElement(AirplaneDown, { size: "small" }) }) => { const { opened, toggleOpened } = usePart(); const { calculatedWidth } = useWidth(); const [{ height: slideHeight }, slideRef] = useBoundingRect({ height: opened ? null : 0 }); const randomId = useRandomIdSeed(); const [isOverflowed, setOverflowed] = React.useState(false); return /*#__PURE__*/React.createElement(StyledWrapper, null, /*#__PURE__*/React.createElement(StyledInnerWrapper, null, /*#__PURE__*/React.createElement(Stack, { align: "center", spacing: "small" }, /*#__PURE__*/React.createElement(StyledDuration, { $minWidth: calculatedWidth || 60 }, /*#__PURE__*/React.createElement(TemporaryText, { as: "div", size: "small", weight: "medium" }, duration)), /*#__PURE__*/React.createElement(StyledDetailsIcon, null, /*#__PURE__*/React.createElement(ItineraryIcon, null, icon)), /*#__PURE__*/React.createElement(StyledSummary, { onClick: ev => { if (isOverflowed && opened) ev.stopPropagation(); } }, /*#__PURE__*/React.createElement(HorizontalScroll, { overflowElevation: true, onOverflow: () => setOverflowed(true), elevationColor: "paletteWhite", scrollSnap: "mandatory" }, summary)), content && (opened ? /*#__PURE__*/React.createElement(ChevronUp, { color: "secondary" }) : /*#__PURE__*/React.createElement(ChevronDown, { color: "secondary" })))), content && /*#__PURE__*/React.createElement(Slide, { maxHeight: slideHeight || 0, expanded: opened, id: randomId("slide"), ariaLabelledBy: randomId("slide") }, /*#__PURE__*/React.createElement(StyledExpandable, { ref: slideRef, onClick: toggleOpened }, /*#__PURE__*/React.createElement(StyledExpandableContent, { $offset: calculatedWidth }, content.map(({ title, items }, idx) => { return ( /*#__PURE__*/ // eslint-disable-next-line react/no-array-index-key React.createElement(React.Fragment, { key: idx }, /*#__PURE__*/React.createElement(StyledHeadingOffset, null, /*#__PURE__*/React.createElement(TemporaryText, { as: "div", size: "small", weight: "medium", spaceAfter: "small" }, title)), /*#__PURE__*/React.createElement(Stack, { direction: "column", spacing: "none", spaceAfter: idx === content.length - 1 ? "none" : "medium" }, items.map(({ icon: itemIcon, name, value }, id) => { return ( /*#__PURE__*/ // eslint-disable-next-line react/no-array-index-key React.createElement(Stack, { flex: true, grow: false, align: "center", key: id }, /*#__PURE__*/React.createElement(StyledIcon, { isFirst: id === 0, isLast: id === items.length - 1 }, itemIcon), /*#__PURE__*/React.createElement(Truncate, null, /*#__PURE__*/React.createElement(Text, { size: "small" }, name)), /*#__PURE__*/React.createElement(Truncate, null, /*#__PURE__*/React.createElement(TemporaryText, { as: "div", size: "small", weight: "medium", align: "right" }, value))) ); }))) ); }))))); }; export default ItinerarySegmentDetail;