All files / src/components/PlacementWrapper index.tsx

0% Statements 0/21
0% Branches 0/14
0% Functions 0/3
0% Lines 0/21

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64                                                                                                                               
import React, { CSSProperties, ReactNode, useMemo } from 'react';
 
import { Box, TooltipProps, useTheme } from '@mui/material';
 
export type PlacementWrapperProps = {
  placedObject: ReactNode;
  children: ReactNode;
  objectPlacement: TooltipProps['placement'];
};
 
/**
 * A component that allows simple management of the location of an object around some children
 *
 * Example:
 * ```
 * <PlacementWrapper objectPlacement={'right-end'} placedObject={<Button icon={'iconComment'} onClick={onClick} />}>
 *   <Box>Stuff and Things</Box>
 * </PlacementWrapper>
 * ```
 */
const PlacementWrapper = ({ placedObject, children, objectPlacement }: PlacementWrapperProps) => {
  const theme = useTheme();
 
  const outsideDirection = useMemo((): CSSProperties['flexDirection'] => {
    if (!objectPlacement) {
      return 'column';
    }
    if (objectPlacement.startsWith('top')) {
      return 'column';
    } else if (objectPlacement.startsWith('bottom')) {
      return 'column-reverse';
    } else if (objectPlacement.startsWith('left')) {
      return 'row';
    } else {
      return 'row-reverse';
    }
  }, [objectPlacement]);
 
  const insideAlignment = useMemo((): CSSProperties['alignContent'] => {
    if (!objectPlacement) {
      return 'center';
    }
    if (objectPlacement.endsWith('start')) {
      return 'flex-start';
    } else if (objectPlacement.endsWith('end')) {
      return 'flex-end';
    } else {
      return 'center';
    }
  }, [objectPlacement]);
 
  return (
    <Box display={'flex'} flexDirection={outsideDirection} flexGrow={1} marginBottom={theme.spacing(2)}>
      <Box alignSelf={insideAlignment} margin={theme.spacing(1)}>
        {placedObject}
      </Box>
 
      {children}
    </Box>
  );
};
 
export default PlacementWrapper;