11import React from "react" ;
22import type { ComponentProps , ComponentPropsWithChildren } from "~/types.js" ;
3+ import { createGridClass , createGridStackingCss } from "./gridStyles.js" ;
34
45export const GridColumnComponent = ( {
56 inputs
@@ -23,7 +24,7 @@ type GridProps = ComponentProps<{
2324 reverseWhenStacked ?: boolean ;
2425} > ;
2526
26- export const GridComponent = ( { inputs, styles, breakpoint } : GridProps ) => {
27+ export const GridComponent = ( { inputs, styles, element } : GridProps ) => {
2728 const { gridLayout = "12" , columns, columnGap, stackAtBreakpoint, reverseWhenStacked } = inputs ;
2829 const rowConfig = gridLayout . split ( "-" ) . map ( size => parseInt ( size ) ) ;
2930 const rows : Column [ ] [ ] = [ ] ;
@@ -36,22 +37,23 @@ export const GridComponent = ({ inputs, styles, breakpoint }: GridProps) => {
3637 // Number of pixels we need to subtract from each cell to ensure they fit in the grid with column gap
3738 const cellWidthReduction = columnGap ? columnGap - columnGap / rowConfig . length : 0 ;
3839
39- const stackColumns = breakpoint === stackAtBreakpoint ;
40+ const gridClass = createGridClass ( element . id ) ;
4041
41- if ( stackColumns ) {
42- styles . flexDirection = reverseWhenStacked ? "column-reverse" : "column" ;
43- }
42+ // Columns stack via a CSS media query (see createGridStackingCss).
43+ const stackCss = createGridStackingCss ( { gridClass, stackAtBreakpoint, reverseWhenStacked } ) ;
4444
4545 return (
46- < div style = { styles } >
46+ < div className = { gridClass } style = { styles } >
47+ { /*
48+ A media query can't be expressed in an inline `style` attribute (that only
49+ holds declarations, not at-rules), so the stacking CSS is emitted as a
50+ scoped <style> tag. A <style> is `display:none` and valid inside <body>,
51+ so it doesn't affect the grid's flex layout.
52+ */ }
53+ { stackCss ? < style dangerouslySetInnerHTML = { { __html : stackCss } } /> : null }
4754 { rows . map ( columns => {
4855 return columns . map ( ( column , i ) => (
49- < Span
50- key = { i }
51- stackColumns = { stackColumns }
52- size = { rowConfig [ i ] }
53- reductionInPx = { cellWidthReduction }
54- >
56+ < Span key = { i } size = { rowConfig [ i ] } reductionInPx = { cellWidthReduction } >
5557 < GridColumnComponent key = { i } inputs = { { children : column . children } } />
5658 </ Span >
5759 ) ) ;
@@ -63,15 +65,16 @@ export const GridComponent = ({ inputs, styles, breakpoint }: GridProps) => {
6365interface SpanProps {
6466 size : number ;
6567 reductionInPx : number ;
66- stackColumns : boolean ;
6768 children : React . ReactNode ;
6869}
6970
70- const Span = ( { size, children, reductionInPx, stackColumns } : SpanProps ) => {
71- const width = stackColumns ? "100%" : `calc(${ ( size / 12 ) * 100 } % - ${ reductionInPx } px)` ;
71+ const Span = ( { size, children, reductionInPx } : SpanProps ) => {
72+ // Base (row) width. The Grid's media query overrides this to 100% when stacked.
73+ const width = `calc(${ ( size / 12 ) * 100 } % - ${ reductionInPx } px)` ;
7274
7375 return (
7476 < div
77+ className = "wb-grid-col"
7578 style = { {
7679 flex : `0 0 ${ width } ` ,
7780 maxWidth : width ,
0 commit comments