import { Spacing, SpaceKey } from "design-system/theme/types"; import React, { Fragment, ReactElement, ReactNode } from "react"; import { ViewProps, ViewStyle } from "react-native"; import { getValidChildren } from "design-system/tools/getValidChildren"; import { Box } from "./Box/Box"; import { useInternalTheme } from "design-system/hooks/useInternalTheme"; export const alignHorizontalToFlexAlign = { center: "center", justify: "space-between", left: "flex-start", right: "flex-end", } as const; type AlignHorizontal = keyof typeof alignHorizontalToFlexAlign; export const alignVerticalToFlexAlign = { bottom: "flex-end", center: "center", top: "flex-start", } as const; type AlignVertical = keyof typeof alignVerticalToFlexAlign; export type RowProps = { children: ReactNode; alignHorizontal?: AlignHorizontal; alignVertical?: AlignVertical; space?: Spacing; horizontalSpace?: Spacing; verticalSpace?: Spacing; testID?: ViewProps["testID"]; flex?: ViewStyle["flex"]; width?: ViewStyle["width"]; } & ( | { separator?: undefined; wrap?: true; } | { separator?: ReactElement; wrap?: false; } ); /** * @description Arranges child nodes horizontally with equal spacing between * them, plus an optional `separator` element. Items can optionally be aligned * horizontally and/or vertically with `alignHorizontal` and `alignVertical`. */ export function Row({ children, alignHorizontal, alignVertical = "center", testID, flex, width, space, horizontalSpace: horizontalSpaceProp, verticalSpace: verticalSpaceProp, wrap, separator, }: RowProps) { const theme = useInternalTheme(); const validChildren = getValidChildren(children); const resolveToken = (value: Spacing) => { if (typeof value === "object") { if (typeof value.custom === "string") { return value.custom; } if (value.custom == null) { return undefined; } return value.custom; } return -1 * theme.config.spacing[value?.replace("-", "") as SpaceKey]; }; const verticalSpace = verticalSpaceProp ?? space; const horizontalSpace = horizontalSpaceProp ?? space; return ( {validChildren.map((child, index) => { const key = typeof child.key !== "undefined" ? child.key : index; const isLast = index + 1 === validChildren.length; if (wrap) { return ( {child} ); } return ( {child} {!!space && !isLast && } {!!separator && !isLast && {separator}} ); })} ); }