Skip to content

Instantly share code, notes, and snippets.

@lukebrooker
Created May 7, 2020 22:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lukebrooker/7e4c2d488487db3359488697e8b5b052 to your computer and use it in GitHub Desktop.
Save lukebrooker/7e4c2d488487db3359488697e8b5b052 to your computer and use it in GitHub Desktop.
An potential Stack component for go1d
import * as React from "react";
import { View } from "@go1d/go1d";
const directionMargins = {
row: "marginRight",
column: "marginBottom",
}
const length = (value) => Array.isArray(value) ? value.length : 1;
const longestLength = (...values) => values
.map((value) => length(value))
.sort((a, b) => b - a)[0]
const padArray = (array, padLength) => {
const paddedArray = Array.isArray(array) ? array : [array];
const initialLength = paddedArray.length;
const lastArrayValue = paddedArray[initialLength - 1];
if (initialLength === padLength) {
return paddedArray;
}
return [...paddedArray, ...Array(padLength - initialLength).fill(lastArrayValue)];
}
const getMargins = (flexDirection, gap) => {
const longestPropLength = longestLength(flexDirection, gap);
const margins = padArray(flexDirection, longestPropLength).map(direction => directionMargins[direction]);
const paddedGap = padArray(gap, longestPropLength);
if (longestPropLength === 1) {
return {
[directionMargins[flexDirection]]: gap,
};
}
return margins.reduce((acc, currentMargin, index) => {
const current = {
marginRight: currentMargin === "marginRight" ? [paddedGap[index]] : [0],
marginBottom: currentMargin === "marginBottom" ? [paddedGap[index]] : [0]
}
if (index === 0) {
return current
}
return {
marginRight: [...acc.marginRight, ...current.marginRight],
marginBottom: [...acc.marginBottom, ...current.marginBottom],
}
}, {})
}
const Stack = ({
gap,
children,
alignItems = "stretch",
justifyContent = "stretch",
flexDirection = "column",
...props,
}) => {
const stackItems = React.Children.toArray(children);
const itemMargins = getMargins(flexDirection, gap);
const lastIndex = stackItems.length - 1
return (
<View
flexDirection={flexDirection}
alignItems={alignItems}
justifyContent={justifyContent}
{...props}
>
{stackItems.map((child, index) =>
React.cloneElement(child, {
...(index !== lastIndex && itemMargins),
})
)}
</View>
);
};
export default Stack
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment