1- import Box , { BoxProps } from '@mui/material/Box' ;
2- import { makeStyles } from 'tss-react/mui' ;
3-
4- const useStyles = makeStyles ( ) ( theme => ( {
5- grid : {
6- display : 'grid' ,
7- gridTemplateColumns : 'repeat(12, 1fr)' ,
8- gridGap : theme . spacing ( 3 ) ,
9- gridAutoFlow : 'dense' ,
10- alignItems : 'start' ,
11- } ,
12- } ) ) ;
1+ import React from "react" ;
2+ import Box , { BoxProps } from "@mui/material/Box" ;
3+ import { makeStyles } from "tss-react/mui" ;
4+ import type { CSSObject } from "tss-react" ;
5+
6+ const BREAKPOINTS = {
7+ sm : 600 ,
8+ md : 900 ,
9+ lg : 1200 ,
10+ xl : 1536 ,
11+ } as const ;
12+
13+ type Breakpoint = "xs" | "sm" | "md" | "lg" | "xl" ;
14+
15+ type GridColumn = Partial < Record < Breakpoint , number | string > > ;
16+
17+ function normalize ( value ?: number | string ) {
18+ if ( typeof value === "number" ) return `span ${ value } ` ;
19+ return value ;
20+ }
21+
22+ function extractGridColumn ( sx : BoxProps [ "sx" ] ) : GridColumn | undefined {
23+ if ( ! sx || typeof sx !== "object" || Array . isArray ( sx ) ) return ;
24+ const gc = ( sx as any ) . gridColumn ;
25+ if ( ! gc || typeof gc !== "object" ) return ;
26+ return gc ;
27+ }
28+
29+ function removeGridColumn ( sx : BoxProps [ "sx" ] ) {
30+ if ( ! sx || typeof sx !== "object" || Array . isArray ( sx ) ) return sx ;
31+ const next = { ...( sx as any ) } ;
32+ delete next . gridColumn ;
33+ return next ;
34+ }
35+
36+ type StyleProps = {
37+ gridColumn : GridColumn ;
38+ } ;
39+
40+ const useStyles = makeStyles < StyleProps > ( ) ( ( theme , { gridColumn } ) => {
41+ const item : CSSObject = { } ;
42+
43+ // default xs behavior
44+ item . gridColumn = normalize ( gridColumn . xs ?? "1 / -1" ) ;
45+
46+ ( Object . keys ( BREAKPOINTS ) as ( keyof typeof BREAKPOINTS ) [ ] ) . forEach ( bp => {
47+ const value = gridColumn [ bp ] ;
48+ if ( ! value ) return ;
49+
50+ item [ `@container (min-width:${ BREAKPOINTS [ bp ] } px)` ] = {
51+ gridColumn : normalize ( value ) ,
52+ } ;
53+ } ) ;
54+
55+ return {
56+ grid : {
57+ display : "grid" ,
58+ gridTemplateColumns : "repeat(12, minmax(0,1fr))" ,
59+ gap : theme . spacing ( 3 ) ,
60+ gridAutoFlow : "row" ,
61+ containerType : "inline-size" ,
62+ } ,
63+ item,
64+ } ;
65+ } ) ;
66+
67+ type GridProps = React . PropsWithChildren <
68+ {
69+ container ?: boolean ;
70+ item ?: boolean ;
71+ } & BoxProps
72+ > ;
1373
1474const Grid = ( {
1575 container = false ,
1676 item = true ,
1777 children,
78+ sx,
1879 ...props
19- } : React . PropsWithChildren <
20- { container ?: boolean ; item ?: boolean } & BoxProps
21- > ) => {
22- const { classes } = useStyles ( ) ;
80+ } : GridProps ) => {
81+ const gridColumn = extractGridColumn ( sx ) ?? { } ;
82+
83+ const { classes, cx } = useStyles ( { gridColumn } ) ;
2384
2485 if ( container ) {
2586 return (
26- < Box { ...props } className = { classes . grid } >
87+ < Box { ...props } sx = { sx } className = { cx ( classes . grid , props . className ) } >
2788 { children }
2889 </ Box >
2990 ) ;
3091 }
92+
3193 if ( item ) {
32- return < Box { ...props } > { children } </ Box > ;
94+ const itemSx = removeGridColumn ( sx ) ;
95+
96+ return (
97+ < Box { ...props } sx = { itemSx } className = { cx ( classes . item , props . className ) } >
98+ { children }
99+ </ Box >
100+ ) ;
33101 }
102+
34103 return null ;
35104} ;
36105
37- export default Grid ;
106+ export default Grid ;
0 commit comments