synapsecns/sanguine

View on GitHub
packages/explorer-ui/components/tailwind/Grid.tsx

Summary

Maintainability
F
4 days
Test Coverage
/*
@NOTE: super repetitive code here is actually necessary...
*/

const GRID_COLS_LOOKUP = {
  0: 'grid-cols-0 ',
  1: 'grid-cols-1 ',
  2: 'grid-cols-2 ',
  3: 'grid-cols-3 ',
  4: 'grid-cols-4 ',
  5: 'grid-cols-5 ',
  6: 'grid-cols-6 ',
  7: 'grid-cols-7 ',
  8: 'grid-cols-8 ',
  9: 'grid-cols-9 ',
  10: 'grid-cols-10 ',
  11: 'grid-cols-11 ',
  12: 'grid-cols-12 ',
  24: 'grid-cols-24 ',
}

const SM_GRID_COLS_LOOKUP = {
  0: 'sm:grid-cols-0 ',
  1: 'sm:grid-cols-1 ',
  2: 'sm:grid-cols-2 ',
  3: 'sm:grid-cols-3 ',
  4: 'sm:grid-cols-4 ',
  5: 'sm:grid-cols-5 ',
  6: 'sm:grid-cols-6 ',
  7: 'sm:grid-cols-7 ',
  8: 'sm:grid-cols-8 ',
  9: 'sm:grid-cols-9 ',
  10: 'sm:grid-cols-10 ',
  11: 'sm:grid-cols-11 ',
  12: 'sm:grid-cols-12 ',
  24: 'sm:grid-cols-24 ',
}

const MD_GRID_COLS_LOOKUP = {
  0: 'md:grid-cols-0 ',
  1: 'md:grid-cols-1 ',
  2: 'md:grid-cols-2 ',
  3: 'md:grid-cols-3 ',
  4: 'md:grid-cols-4 ',
  5: 'md:grid-cols-5 ',
  6: 'md:grid-cols-6 ',
  7: 'md:grid-cols-7 ',
  8: 'md:grid-cols-8 ',
  9: 'md:grid-cols-9 ',
  10: 'md:grid-cols-10 ',
  11: 'md:grid-cols-11 ',
  12: 'md:grid-cols-12 ',
  24: 'md:grid-cols-24 ',
}

const LG_GRID_COLS_LOOKUP = {
  0: 'lg:grid-cols-0 ',
  1: 'lg:grid-cols-1 ',
  2: 'lg:grid-cols-2 ',
  3: 'lg:grid-cols-3 ',
  4: 'lg:grid-cols-4 ',
  5: 'lg:grid-cols-5 ',
  6: 'lg:grid-cols-6 ',
  7: 'lg:grid-cols-7 ',
  8: 'lg:grid-cols-8 ',
  9: 'lg:grid-cols-9 ',
  10: 'lg:grid-cols-10 ',
  11: 'lg:grid-cols-11 ',
  12: 'lg:grid-cols-12 ',
  24: 'lg:grid-cols-24 ',
}

const XL_GRID_COLS_LOOKUP = {
  0: 'xl:grid-cols-0 ',
  1: 'xl:grid-cols-1 ',
  2: 'xl:grid-cols-2 ',
  3: 'xl:grid-cols-3 ',
  4: 'xl:grid-cols-4 ',
  5: 'xl:grid-cols-5 ',
  6: 'xl:grid-cols-6 ',
  7: 'xl:grid-cols-7 ',
  8: 'xl:grid-cols-8 ',
  9: 'xl:grid-cols-9 ',
  10: 'xl:grid-cols-10 ',
  11: 'xl:grid-cols-11 ',
  12: 'xl:grid-cols-12 ',
  24: 'xl:grid-cols-24 ',
}

const GAP_LOOKUP = {
  0: 'gap-0 ',
  1: 'gap-1 ',
  2: 'gap-2 ',
  3: 'gap-3 ',
  4: 'gap-4 ',
  5: 'gap-5 ',
  6: 'gap-6 ',
  8: 'gap-8 ',
  10: 'gap-10 ',
  12: 'gap-12 ',
  16: 'gap-16 ',
  20: 'gap-20 ',
  24: 'gap-24 ',
}

const SIZE_GAP_LOOKUP = {
  xs: {
    0: 'gap-0 ',
    1: 'gap-1 ',
    2: 'gap-2 ',
    3: 'gap-3 ',
    4: 'gap-4 ',
    5: 'gap-5 ',
    6: 'gap-6 ',
    8: 'gap-8 ',
    10: 'gap-10 ',
    12: 'gap-12 ',
    16: 'gap-16 ',
    20: 'gap-20 ',
    24: 'gap-24 ',
  },
  sm: {
    0: 'sm:gap-0 ',
    1: 'sm:gap-1 ',
    2: 'sm:gap-2 ',
    3: 'sm:gap-3 ',
    4: 'sm:gap-4 ',
    5: 'sm:gap-5 ',
    6: 'sm:gap-6 ',
    8: 'sm:gap-8 ',
    10: 'sm:gap-10 ',
    12: 'sm:gap-12 ',
    16: 'sm:gap-16 ',
    20: 'sm:gap-20 ',
    24: 'sm:gap-24 ',
  },
  md: {
    0: 'md:gap-0 ',
    1: 'md:gap-1 ',
    2: 'md:gap-2 ',
    3: 'md:gap-3 ',
    4: 'md:gap-4 ',
    5: 'md:gap-5 ',
    6: 'md:gap-6 ',
    8: 'md:gap-8 ',
    10: 'md:gap-10 ',
    12: 'md:gap-12 ',
    16: 'md:gap-16 ',
    20: 'md:gap-20 ',
    24: 'md:gap-24 ',
  },
  lg: {
    0: 'lg:gap-0 ',
    1: 'lg:gap-1 ',
    2: 'lg:gap-2 ',
    3: 'lg:gap-3 ',
    4: 'lg:gap-4 ',
    5: 'lg:gap-5 ',
    6: 'lg:gap-6 ',
    8: 'lg:gap-8 ',
    10: 'lg:gap-10 ',
    12: 'lg:gap-12 ',
    16: 'lg:gap-16 ',
    20: 'lg:gap-20 ',
    24: 'lg:gap-24 ',
  },
}

const GAP_X_LOOKUP = {
  0: 'gap-x-0 ',
  1: 'gap-x-1 ',
  2: 'gap-x-2 ',
  3: 'gap-x-3 ',
  4: 'gap-x-4 ',
  5: 'gap-x-5 ',
  6: 'gap-x-6 ',
  8: 'gap-x-8 ',
  10: 'gap-x-10 ',
  12: 'gap-x-12 ',
  16: 'gap-x-16 ',
  20: 'gap-x-20 ',
  24: 'gap-x-24 ',
}

const GAP_Y_LOOKUP = {
  0: 'gap-y-0 ',
  1: 'gap-y-1 ',
  2: 'gap-y-2 ',
  3: 'gap-y-3 ',
  4: 'gap-y-4 ',
  5: 'gap-y-5 ',
  6: 'gap-y-6 ',
  8: 'gap-y-8 ',
  10: 'gap-y-10 ',
  12: 'gap-y-12 ',
  16: 'gap-y-16 ',
  20: 'gap-y-20 ',
  24: 'gap-y-24 ',
}

interface Props {
  children: React.ReactNode
  cols?: {
    xs?: number
    sm?: number
    md?: number
    lg?: number
    xl?: number
  }
  gap?: number | Array<number>
  gapX?: number
  gapY?: number
  as?: React.ElementType
  className?: string
  [key: string]: any
}

export const Grid = ({
  children,
  cols,
  gap,
  gapX,
  gapY,
  as,
  className: providedClassName,
  ...props
}: Props) => {
  let novelClassName = 'grid '

  const { xs, sm, md, lg, xl } = cols ?? {}

  if (cols ?? false) {
    if (xs ?? false) {
      novelClassName += GRID_COLS_LOOKUP[xs]
    }
    if (sm ?? false) {
      novelClassName += SM_GRID_COLS_LOOKUP[sm]
    }
    if (md ?? false) {
      novelClassName += MD_GRID_COLS_LOOKUP[md]
    }
    if (lg ?? false) {
      novelClassName += LG_GRID_COLS_LOOKUP[lg]
    }
    if (xl ?? false) {
      novelClassName += XL_GRID_COLS_LOOKUP[xl]
    }
  } else {
    novelClassName += GRID_COLS_LOOKUP[12]
  }

  if (!((gap ?? false) || (gapX ?? false) || (gapY ?? false))) {
    novelClassName += GAP_LOOKUP[0]
  }

  if (gap ?? false) {
    if (Number.isInteger(gap)) {
      novelClassName += GAP_LOOKUP[String(gap)]
    } else {
      for (const [screenSize, gapSize] of (gap as Array<number>).entries()) {
        novelClassName += SIZE_GAP_LOOKUP[screenSize][gapSize]
      }
    }
  }

  if (gapX ?? false) {
    novelClassName += GAP_X_LOOKUP[gapX]
  }

  if (gapY ?? false) {
    novelClassName += GAP_Y_LOOKUP[gapY]
  }

  if (providedClassName ?? false) {
    novelClassName = `${novelClassName} ${providedClassName} `
  }

  const BaseComponent = as ?? 'div'

  return (
    <BaseComponent className={novelClassName} {...props}>
      {children}
    </BaseComponent>
  )
}