diff --git a/src/docs/pages/grid/GridAutoRows.tsx b/src/docs/pages/grid/GridAutoRows.tsx new file mode 100644 index 00000000..01654713 --- /dev/null +++ b/src/docs/pages/grid/GridAutoRows.tsx @@ -0,0 +1,140 @@ +import { VuiGrid, VuiGridItem, VuiCard, VuiText, VuiSpacer, VuiTitle } from "../../../lib"; + +export const GridAutoRows = () => { + const longContent = ( + <> + +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. +

+
+ + +

+ Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. + Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium. +

+
+ + +

+ Totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt + explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur + magni dolores eos qui ratione voluptatem sequi nesciunt. +

+
+ + +

+ Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non + numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. +

+
+ + ); + + return ( + <> + +

Grid with autoRows="200px"

+
+ + + + +

+ This grid uses autoRows="200px" to set a fixed height of 200px for all implicitly created rows. Notice how all + rows have the same height regardless of content, and cards with long content become scrollable. This becomes + particularly relevant as the number of rows increases as the size of the container gets smaller. +

+
+ + + + + + Card 1} body={longContent} /> + + + + Card 2} + body={ + +

Short content in this card.

+
+ } + /> +
+ + + Card 3} body={longContent} /> + +
+ + + + +

Grid without autoRows

+
+ + + + +

+ This grid has no autoRows value set. Notice how on larger containers, the cards have the same height (thanks + to templateRows="200px") but as the container gets smaller, the newly created rows don't adhere to a fixed + height. +

+
+ + + + + + Card 1} body={longContent} /> + + + + Card 2} + body={ + +

Short content in this card.

+
+ } + /> +
+ + + Card 3} body={longContent} /> + +
+ + ); +}; diff --git a/src/docs/pages/grid/index.tsx b/src/docs/pages/grid/index.tsx index 0bb6b450..e775b140 100644 --- a/src/docs/pages/grid/index.tsx +++ b/src/docs/pages/grid/index.tsx @@ -3,12 +3,14 @@ import { GridSpanning } from "./GridSpanning"; import { GridSimple } from "./GridSimple"; import { GridAlignment } from "./GridAlignment"; import { GridResponsive } from "./GridResponsive"; +import { GridAutoRows } from "./GridAutoRows"; const GridSource = require("!!raw-loader!./Grid"); const GridSpanningSource = require("!!raw-loader!./GridSpanning"); const GridSimpleSource = require("!!raw-loader!./GridSimple"); const GridAlignmentSource = require("!!raw-loader!./GridAlignment"); const GridResponsiveSource = require("!!raw-loader!./GridResponsive"); +const GridAutoRowsSource = require("!!raw-loader!./GridAutoRows"); export const grid = { name: "Grid", @@ -38,6 +40,11 @@ export const grid = { name: "Responsive columns", component: , source: GridResponsiveSource.default.toString() + }, + { + name: "Auto rows", + component: , + source: GridAutoRowsSource.default.toString() } ] }; diff --git a/src/lib/components/grid/Grid.tsx b/src/lib/components/grid/Grid.tsx index c82c9613..44647694 100644 --- a/src/lib/components/grid/Grid.tsx +++ b/src/lib/components/grid/Grid.tsx @@ -12,15 +12,7 @@ type GridAlignItems = (typeof GRID_ALIGN_ITEMS)[number]; const GRID_JUSTIFY_ITEMS = ["start", "end", "center", "stretch"] as const; type GridJustifyItems = (typeof GRID_JUSTIFY_ITEMS)[number]; -const GRID_ALIGN_CONTENT = [ - "start", - "end", - "center", - "stretch", - "spaceAround", - "spaceBetween", - "spaceEvenly" -] as const; +const GRID_ALIGN_CONTENT = ["start", "end", "center", "stretch", "spaceAround", "spaceBetween", "spaceEvenly"] as const; type GridAlignContent = (typeof GRID_ALIGN_CONTENT)[number]; const GRID_JUSTIFY_CONTENT = [ @@ -75,6 +67,7 @@ type Props = { spacing?: FlexSpacing; templateColumns?: ResponsiveGridValue; templateRows?: string; + autoRows?: ResponsiveGridValue; alignItems?: GridAlignItems; justifyItems?: GridJustifyItems; alignContent?: GridAlignContent; @@ -90,6 +83,7 @@ export const VuiGrid = ({ spacing = "m", templateColumns, templateRows, + autoRows, alignItems, justifyItems, alignContent, @@ -99,10 +93,10 @@ export const VuiGrid = ({ className, ...rest }: Props) => { - const classes = classNames("vuiGridContainer", className); const isResponsiveTemplateColumns = templateColumns && typeof templateColumns === "object"; + const isResponsiveAutoRows = autoRows && typeof autoRows === "object"; const contentClasses = classNames( "vuiGrid", @@ -111,7 +105,8 @@ export const VuiGrid = ({ [`vuiGrid--columns${columns}`]: !templateColumns && columns, "vuiGrid--inline": inline, "vuiGrid--fullWidth": fullWidth, - "vuiGrid--responsive": isResponsiveTemplateColumns + "vuiGrid--responsive": isResponsiveTemplateColumns, + "vuiGrid--responsiveAutoRows": isResponsiveAutoRows }, alignItems && alignItemsClassMap[alignItems], justifyItems && justifyItemsClassMap[justifyItems], @@ -148,12 +143,31 @@ export const VuiGrid = ({ gridStyle.gridTemplateRows = templateRows; } + if (autoRows) { + if (typeof autoRows === "string") { + gridStyle.gridAutoRows = autoRows; + } else { + // Implement cascading: each breakpoint inherits from the previous if not defined + const defaultValue = autoRows.default; + const smValue = autoRows.sm || defaultValue; + const mdValue = autoRows.md || smValue; + const lgValue = autoRows.lg || mdValue; + + if (smValue) { + gridStyle["--grid-auto-rows-sm"] = smValue; + } + if (mdValue) { + gridStyle["--grid-auto-rows-md"] = mdValue; + } + if (lgValue) { + gridStyle["--grid-auto-rows-lg"] = lgValue; + } + } + } + return (
-
0 ? gridStyle : undefined} - > +
0 ? gridStyle : undefined}> {children}
diff --git a/src/lib/components/grid/_index.scss b/src/lib/components/grid/_index.scss index 2584d5ac..6b00014d 100644 --- a/src/lib/components/grid/_index.scss +++ b/src/lib/components/grid/_index.scss @@ -82,6 +82,20 @@ $spacing: ( } } +// Responsive grid auto rows using CSS custom properties +.vuiGrid--responsiveAutoRows { + // Small (applies from 0px up - default/mobile-first) + grid-auto-rows: var(--grid-auto-rows-sm); + + @container (width > 500px) { + grid-auto-rows: var(--grid-auto-rows-md); + } + + @container (width > 800px) { + grid-auto-rows: var(--grid-auto-rows-lg); + } +} + // Alignment - align-items .vuiGrid--alignItemsStart { align-items: start;