import { Box as MUIBox, BoxProps as MUIBoxProps } from '@mui/material'; import { FC, useMemo } from 'react'; type FlexBoxDirection = 'column' | 'row'; type FlexBoxOptionalProps = { row?: boolean; lg?: FlexBoxDirection; md?: FlexBoxDirection; sm?: FlexBoxDirection; spacing?: number | string; xl?: FlexBoxDirection; xs?: FlexBoxDirection; }; type FlexBoxProps = MUIBoxProps & FlexBoxOptionalProps; const FLEX_BOX_DEFAULT_PROPS: Required< Omit > & Pick = { row: false, lg: undefined, md: undefined, sm: undefined, spacing: '1em', xl: undefined, xs: 'column', }; const FlexBox: FC = ({ lg: dLg = FLEX_BOX_DEFAULT_PROPS.lg, md: dMd = FLEX_BOX_DEFAULT_PROPS.md, row: isRow, sm: dSm = FLEX_BOX_DEFAULT_PROPS.sm, spacing = FLEX_BOX_DEFAULT_PROPS.spacing, sx, xl: dXl = FLEX_BOX_DEFAULT_PROPS.xl, xs: dXs = FLEX_BOX_DEFAULT_PROPS.xs, ...muiBoxRestProps }) => { const xs = useMemo(() => (isRow ? 'row' : dXs), [dXs, isRow]); const sm = useMemo(() => dSm || xs, [dSm, xs]); const md = useMemo(() => dMd || sm, [dMd, sm]); const lg = useMemo(() => dLg || md, [dLg, md]); const xl = useMemo(() => dXl || lg, [dXl, lg]); const mapToSx: Record< FlexBoxDirection, { alignItems: string; marginLeft: string | number; marginTop: string | number; } > = useMemo( () => ({ column: { alignItems: 'normal', marginLeft: 0, marginTop: spacing, }, row: { alignItems: 'center', marginLeft: spacing, marginTop: 0, }, }), [spacing], ); return ( :not(:first-child)': { marginLeft: { xs: mapToSx[xs].marginLeft, sm: mapToSx[sm].marginLeft, md: mapToSx[md].marginLeft, lg: mapToSx[lg].marginLeft, xl: mapToSx[xl].marginLeft, }, marginTop: { xs: mapToSx[xs].marginTop, sm: mapToSx[sm].marginTop, md: mapToSx[md].marginTop, lg: mapToSx[lg].marginTop, xl: mapToSx[xl].marginTop, }, }, ...sx, }, }} /> ); }; FlexBox.defaultProps = FLEX_BOX_DEFAULT_PROPS; export type { FlexBoxProps }; export default FlexBox;