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.

121 lines (119 loc) 4.54 kB
"use client"; import React from "react"; import cx from "clsx"; import { getDisplayClasses, getDirectionClasses, getAlignItemsClasses, getWrapClasses, getGrowClasses, getShrinkClasses, getAlignContentClasses, getJustifyClasses, getSpacingClasses, getSpaceAfterClasses } from "../common/tailwind"; import { QUERIES } from "../utils/mediaQuery/consts"; import { DIRECTION } from "../common/tailwind/direction"; import { SPACING } from "../common/tailwind/spacing"; import { ALIGN } from "../common/tailwind/alignItems"; import { JUSTIFY } from "../common/tailwind/justify"; const shouldUseFlex = props => props.flex || Object.keys(props).map(prop => ["spacing", "spaceAfter", "dataTest", "children"].includes(prop)).includes(false); // use margins instead of gap, works with block const shouldUseLegacy = props => { if (props.legacy) return true; if (!shouldUseFlex(props) && Boolean(props.spacing)) return true; return false; }; const Stack = props => { const { children, as: ComponentTag = "div", dataTest, basis, mediumMobile, largeMobile, tablet, desktop, largeDesktop } = props; const viewportProps = { mediumMobile, largeMobile, tablet, desktop, largeDesktop }; const defaultMediaProps = React.useMemo(() => { const isFlex = shouldUseFlex(props); const { spacing = SPACING.medium, spaceAfter, direction = isFlex ? DIRECTION.ROW : DIRECTION.COLUMN, grow = true, justify = JUSTIFY.START, shrink = false, wrap = false, flex, legacy = shouldUseLegacy({ ...props, spacing }), align = ALIGN.START, inline = false } = props; return { flex: flex || isFlex, legacy, direction, spacing, grow, inline, justify, align, shrink, wrap, spaceAfter }; }, [props]); const vars = { "--basis": basis, "--mm-basis": mediumMobile?.basis, "--lm-basis": largeMobile?.basis, "--tb-basis": tablet?.basis, "--de-basis": desktop?.basis, "--ld-basis": largeDesktop?.basis }; const varClasses = [vars["--basis"] != null && "basis-[var(--basis)]", vars["--mm-basis"] != null && "mm:basis-[var(--mm-basis)]", vars["--lm-basis"] != null && "lm:basis-[var(--lm-basis)]", vars["--tb-basis"] != null && "tb:basis-[var(--tb-basis)]", vars["--de:basis"] != null && "de:basis-[var(--de-basis)]", vars["--ld:basis"] != null && "ld:basis-[var(--ld-basis)]"]; const getProperty = React.useCallback((property, viewports, index) => { const viewport = viewports[index]; const found = props[viewport]?.[property]; if (typeof found !== "undefined") return found; if (index > 0) return getProperty(property, viewports, index - 1); return defaultMediaProps[property]; }, [props, defaultMediaProps]); const getTailwindTokensForMedia = (opts, viewport) => { if (!opts) return ""; const { spaceAfter, align, wrap, grow, shrink, justify, direction, spacing, inline, flex, legacy } = opts; return cx(typeof spaceAfter !== "undefined" && getSpaceAfterClasses(spaceAfter, viewport), typeof align !== "undefined" && getAlignItemsClasses(align, viewport), typeof align !== "undefined" && getAlignContentClasses(align, viewport), typeof wrap !== "undefined" && getWrapClasses(wrap, viewport), typeof grow !== "undefined" && getGrowClasses(grow, viewport), typeof shrink !== "undefined" && getShrinkClasses(shrink, viewport), typeof justify !== "undefined" && getJustifyClasses(justify, viewport), getDirectionClasses(direction, viewport), flex || inline ? getDisplayClasses(inline ? "inline-flex" : "flex", viewport) : "block", getSpacingClasses(spacing, viewport, direction, legacy), inline === false && "w-full"); }; return ( /*#__PURE__*/ // @ts-expect-error orbit string as React.createElement(ComponentTag, { "data-test": dataTest, style: vars, className: cx(getTailwindTokensForMedia(defaultMediaProps), ...varClasses, Object.values(QUERIES).map((viewport, index, viewports) => { if (!viewportProps[viewport]) return null; return getTailwindTokensForMedia({ ...props[viewport], direction: getProperty("direction", viewports, index), spacing: getProperty("spacing", viewports, index), legacy: getProperty("legacy", viewports, index) }, viewport); })) }, children) ); }; export default Stack;