UNPKG

@kiwicom/orbit-components

Version:

<div align="center"> <a href="https://orbit.kiwi" target="_blank"> <img alt="orbit-components" src="https://orbit.kiwi/wp-content/uploads/2018/08/orbit-components.png" srcset="https://orbit.kiwi/wp-content/uploads/2018/08/orbit-components@2x.png 2x"

115 lines (101 loc) 5.59 kB
import * as React from "react"; import styled, { css } from "styled-components"; import media from "../utils/media"; import defaultTokens from "../defaultTokens"; import { ALIGNS, DIRECTIONS, SPACINGS, TOKENS } from "./consts"; import { StyledButton } from "../Button"; import getSpacingToken from "../common/getSpacingToken"; // TODO: use tokens for spacings const getSpacing = (isDesktop = false) => ({ spacing, direction, desktop }) => () => { const finalSpacing = isDesktop && desktop && desktop.spacing || spacing; const finalDirection = isDesktop && desktop && desktop.direction || direction; const finalType = isDesktop ? TOKENS.SPACING : TOKENS.MOBILESPACING; const tokens = { [TOKENS.SPACING]: { [SPACINGS.EXTRATIGHT]: "2px", [SPACINGS.TIGHT]: "4px", [SPACINGS.CONDENSED]: "8px", [SPACINGS.COMPACT]: "12px", [SPACINGS.NATURAL]: "16px", [SPACINGS.COMFY]: "24px", [SPACINGS.LOOSE]: "32px", [SPACINGS.EXTRALOOSE]: "40px" }, [TOKENS.MOBILESPACING]: { [SPACINGS.EXTRATIGHT]: "2px", [SPACINGS.TIGHT]: "4px", [SPACINGS.CONDENSED]: "8px", [SPACINGS.COMPACT]: "12px", [SPACINGS.NATURAL]: "16px", [SPACINGS.COMFY]: "20px", [SPACINGS.LOOSE]: "28px", [SPACINGS.EXTRALOOSE]: "36px" } }; // TODO: rtl here return finalDirection === DIRECTIONS.COLUMN ? `0 0 ${tokens[finalType][finalSpacing]} 0` : `0 ${tokens[finalType][finalSpacing]} 0 0`; }; const getAlign = (name = ALIGNS.START, self = false) => { const align = self && name === ALIGNS.EVEN ? ALIGNS.START : name; const tokens = { [ALIGNS.START]: "flex-start", [ALIGNS.END]: "flex-end", [ALIGNS.CENTER]: "center", [ALIGNS.EVEN]: "space-between" }; return tokens[align]; }; const isDefined = property => ({ flex, desktop }) => flex && desktop && typeof property !== "undefined"; const StyledStack = styled(({ className, children }) => React.createElement( "div", { className: className }, children )).withConfig({ displayName: "Stack__StyledStack" })(["display:", ";flex-direction:", ";flex-wrap:", ";flex-grow:", ";flex-shrink:", ";flex-basis:", ";justify-content:", ";align-items:", ";align-content:", ";margin-bottom:", ";& > *{margin:", ";&:last-child{margin:0;}}& > ", "{align-self:", ";}", ";"], ({ inline, flex }) => flex && (inline ? "inline-flex" : "flex"), ({ direction, flex }) => flex && (direction === DIRECTIONS.ROW ? "row" : "column"), ({ wrap, flex }) => flex && (wrap ? "wrap" : "nowrap"), ({ grow, flex }) => flex && (grow ? "1" : "0"), ({ shrink, flex }) => flex && (shrink ? "1" : "0"), ({ basis, flex }) => flex && basis, ({ flex, align, direction }) => flex && (direction === DIRECTIONS.ROW || align) && getAlign(align), ({ flex }) => flex && "stretch", ({ align, direction, flex }) => flex && (direction === DIRECTIONS.COLUMN || align) && getAlign(align), getSpacingToken, ({ align }) => align !== ALIGNS.EVEN && getSpacing(), StyledButton, ({ align }) => getAlign(align, true), media.desktop` & > * { margin: ${getSpacing(true)}; } // TODO other block components & > ${StyledButton} { align-self: ${({ desktop, align }) => desktop && desktop.align !== align && getAlign(desktop.align === ALIGNS.EVEN ? ALIGNS.START : desktop.align)}; } ${({ desktop }) => desktop && css(["display:", ";flex-direction:", ";flex-wrap:", ";flex-grow:", ";flex-shrink:", ";flex-basis:", ";justify-content:", ";align-content:", ";"], ({ inline }) => isDefined(desktop.inline) && inline !== desktop.inline && (desktop.inline ? "inline-flex" : "flex"), ({ direction, flex }) => flex && desktop && typeof desktop.direction !== "undefined" && direction !== desktop.direction && (desktop.direction === DIRECTIONS.ROW ? "row" : "column"), ({ wrap, flex }) => flex && desktop && typeof desktop.wrap !== "undefined" && wrap !== desktop.wrap && (desktop.wrap ? "wrap" : "nowrap"), ({ grow, flex }) => flex && desktop && typeof desktop.grow !== "undefined" && grow !== desktop.grow && (desktop.grow ? "1" : "0"), ({ shrink, flex }) => flex && desktop && typeof desktop.shrink !== "undefined" && shrink !== desktop.shrink && (desktop.shrink ? "1" : "0"), ({ basis, flex }) => flex && desktop && typeof desktop.basis !== "undefined" && basis !== desktop.basis && desktop.basis, ({ flex, align, direction }) => flex && desktop && desktop.direction && (direction !== desktop.direction || align !== desktop.align) && desktop.direction === DIRECTIONS.ROW && getAlign(desktop.align || align), ({ align, direction, flex }) => flex && desktop && desktop.direction && (direction !== desktop.direction || align !== desktop.align) && desktop.direction === DIRECTIONS.COLUMN && getAlign(desktop.align || align))} `); StyledStack.defaultProps = { theme: defaultTokens }; const Stack = props => { const { inline = false, direction = DIRECTIONS.COLUMN, spacing = SPACINGS.NATURAL, align = ALIGNS.START, grow = true, wrap = false, shrink = false, basis, desktop, spaceAfter, children } = props; const flex = Object.keys(props).map(item => !(item === "children" || item === "spaceAfter" || item === "spacing")).includes(true); return React.createElement( StyledStack, { flex: flex, direction: direction, align: align, wrap: wrap, grow: grow, basis: basis, inline: inline, shrink: shrink, spacing: spacing, spaceAfter: spaceAfter, desktop: desktop }, children ); }; export default Stack;