Grid.tsx 1.1 KB

1234567891011121314151617181920212223242526272829303132333435
  1. import React from 'react'
  2. import styled from '@emotion/styled'
  3. import useResizeObserver from 'use-resize-observer'
  4. import { spacing } from '../../theme'
  5. const Container = styled.div<GridProps>`
  6. display: grid;
  7. gap: ${(props) => props.gap};
  8. grid-template-columns: repeat(${(props) => `auto-${props.repeat}`}, minmax(min(270px, 100%), 1fr));
  9. `
  10. type GridProps = {
  11. gap?: number | string
  12. repeat?: 'fit' | 'fill'
  13. className?: string
  14. onResize?: (sizes: number[]) => void
  15. }
  16. const Grid: React.FC<GridProps> = ({ children, className, gap = spacing.xl, repeat = 'fit', onResize, ...props }) => {
  17. const { ref: gridRef } = useResizeObserver<HTMLDivElement>({
  18. onResize: () => {
  19. if (onResize && gridRef.current) {
  20. const computedStyles = window.getComputedStyle(gridRef.current)
  21. const columnSizes = computedStyles.gridTemplateColumns.split(' ').map(parseFloat)
  22. onResize(columnSizes)
  23. }
  24. },
  25. })
  26. return (
  27. <Container {...props} repeat={repeat} className={className} ref={gridRef} gap={gap}>
  28. {children}
  29. </Container>
  30. )
  31. }
  32. export default Grid