flex.tsx 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import type {CSSProperties} from 'react';
  2. import styled from '@emotion/styled';
  3. import type {CssSize} from 'sentry/utils/number/toPixels';
  4. import toPixels from 'sentry/utils/number/toPixels';
  5. interface FlexProps {
  6. align?: CSSProperties['alignItems'];
  7. column?: boolean;
  8. flex?: CSSProperties['flex'];
  9. gap?: number | CssSize;
  10. h?: number | CssSize;
  11. justify?: CSSProperties['justifyContent'];
  12. p?: number | CssSize;
  13. w?: number | CssSize;
  14. wrap?: CSSProperties['flexWrap'];
  15. }
  16. const FlexContainer = styled('div')<FlexProps>`
  17. /* these can all come from a better base primitive */
  18. display: flex;
  19. height: ${p => toPixels(p.h)};
  20. width: ${p => toPixels(p.w)};
  21. padding: ${p => toPixels(p.p)};
  22. /* flex specific */
  23. flex-direction: ${p => (p.column ? 'column' : 'row')};
  24. justify-content: ${p => p.justify};
  25. align-items: ${p => p.align};
  26. gap: ${p => toPixels(p.gap)};
  27. flex-wrap: ${p => p.wrap};
  28. flex: ${p => p.flex ?? 'initial'};
  29. `;
  30. interface FlexItemProps {
  31. basis?: CSSProperties['flexBasis'];
  32. grow?: CSSProperties['flexGrow'];
  33. shrink?: CSSProperties['flexShrink'];
  34. }
  35. const FlexItem = styled('div')<FlexItemProps>`
  36. flex-grow: ${p => p.grow ?? 0};
  37. flex-shrink: ${p => p.shrink ?? 1};
  38. flex-basis: ${p => p.basis ?? 'auto'};
  39. overflow: hidden;
  40. `;
  41. export const Flex = Object.assign(FlexContainer, {
  42. ...FlexContainer,
  43. Item: FlexItem,
  44. });