From 71569800638ebbd04287580adc47435edf606543 Mon Sep 17 00:00:00 2001 From: Wanjohi Date: Tue, 22 Jul 2025 17:14:10 +0300 Subject: [PATCH] feat(web): Use a better grid system --- .../src/components/astro/HeroComponent.astro | 48 ++-- packages/web/src/components/solidjs/Grid.tsx | 252 +++++++++--------- 2 files changed, 154 insertions(+), 146 deletions(-) diff --git a/packages/web/src/components/astro/HeroComponent.astro b/packages/web/src/components/astro/HeroComponent.astro index 4e4d5346..4dc6c275 100644 --- a/packages/web/src/components/astro/HeroComponent.astro +++ b/packages/web/src/components/astro/HeroComponent.astro @@ -1,5 +1,24 @@ --- import { Stack, Grid } from "../solidjs/index.ts"; + +// Define which areas are occupied by content at different breakpoints +const occupiedAreas = { + xs: [ + { startRow: 2, endRow: 6, startCol: 1, endCol: 9 }, // Hero content spans rows 2-6, cols 1-9 + ], + sm: [ + { startRow: 2, endRow: 5, startCol: 2, endCol: 8 }, // Hero content spans rows 2-5, cols 2-8 + ], + smd: [ + { startRow: 2, endRow: 4, startCol: 2, endCol: 12 }, // Hero content spans rows 2-4, cols 2-12 + ], + md: [ + { startRow: 2, endRow: 4, startCol: 2, endCol: 12 }, // Same as smd + ], + lg: [ + { startRow: 2, endRow: 6, startCol: 2, endCol: 12 }, // Same as smd + ], +}; ---
- - - - - -
diff --git a/packages/web/src/components/solidjs/Grid.tsx b/packages/web/src/components/solidjs/Grid.tsx index 58f0dc00..58451028 100644 --- a/packages/web/src/components/solidjs/Grid.tsx +++ b/packages/web/src/components/solidjs/Grid.tsx @@ -1,46 +1,68 @@ -import { splitProps, For } from "solid-js"; -import type { ParentProps, JSX } from 'solid-js'; +import { type ParentProps, splitProps, For, type JSX } from "solid-js"; import styles from "./index.module.css"; +export interface GridCell { + startRow: number; + endRow: number; + startCol: number; + endCol: number; +} + +export interface GridOccupiedAreas { + xs?: GridCell[]; + sm?: GridCell[]; + smd?: GridCell[]; + md?: GridCell[]; + lg?: GridCell[]; +} + export interface GridRootProps { - gridRows?: number; + xsGridRows?: number; + smGridRows?: number; + mdGridRows?: number; + xsGridColumns?: number; smGridColumns?: number; mdGridColumns?: number; - lgGridColumns?: number; smHeight?: string; - heroHeading?: boolean; + occupiedAreas?: GridOccupiedAreas; class?: string; style?: JSX.CSSProperties; } const defaultProps: GridRootProps = { - gridRows: 1, - lgGridColumns: 1, - mdGridColumns: 1, - heroHeading: false, + xsGridRows: 6, + smGridRows: 5, + mdGridRows: 4, + xsGridColumns: 8, + smGridColumns: 8, + mdGridColumns: 12, smHeight: "calc(var(--width) / var(--grid-cols) * var(--grid-rows))", - smGridColumns: 1, + occupiedAreas: {}, } export function Root(props: ParentProps) { const [local, others] = splitProps({ ...defaultProps, ...props }, [ - "gridRows", + "xsGridRows", + "smGridRows", + "mdGridRows", + "xsGridColumns", "smGridColumns", "mdGridColumns", - "lgGridColumns", "smHeight", - "heroHeading", + "occupiedAreas", "class", "style", "children" ]); const styleVars: Record = { - ...(local.smHeight && { "--sm-height": local.smHeight }), + ...(local.xsGridRows && { "--xs-grid-rows": local.xsGridRows.toString() }), + ...(local.smGridRows && { "--sm-grid-rows": local.smGridRows.toString() }), + ...(local.mdGridRows && { "--md-grid-rows": local.mdGridRows.toString() }), + ...(local.xsGridColumns && { "--xs-grid-cols": local.xsGridColumns.toString() }), ...(local.smGridColumns && { "--sm-grid-cols": local.smGridColumns.toString() }), ...(local.mdGridColumns && { "--md-grid-cols": local.mdGridColumns.toString() }), - ...(local.lgGridColumns && { "--lg-grid-cols": local.lgGridColumns.toString() }), - ...(local.gridRows && { "--grid-rows": local.gridRows.toString() }), + ...(local.smHeight && { "--sm-height": local.smHeight }), } const styleStr = Object.entries({ ...styleVars, ...local.style }) @@ -48,128 +70,112 @@ export function Root(props: ParentProps) { .map(([k, v]) => `${k}: ${v}`) .join("; "); + // Helper function to check if a cell is occupied + const isCellOccupied = (breakpoint: keyof GridOccupiedAreas, col: number, row: number): boolean => { + const areas = local.occupiedAreas?.[breakpoint] || []; + return areas.some(area => + col >= area.startCol && col < area.endCol && + row >= area.startRow && row < area.endRow + ); + }; + + // Helper function to determine border styles for a cell + const getCellBorderStyle = ( + breakpoint: keyof GridOccupiedAreas, + col: number, + row: number, + maxCols: number, + maxRows: number + ) => { + const isOccupied = isCellOccupied(breakpoint, col, row); + const isLastCol = col === maxCols; + const isLastRow = row === maxRows; + + // Check if the cell to the right is also occupied (to remove internal borders) + const rightCellOccupied = !isLastCol && isCellOccupied(breakpoint, col + 1, row); + // Check if the cell below is also occupied (to remove internal borders) + const bottomCellOccupied = !isLastRow && isCellOccupied(breakpoint, col, row + 1); + + return { + // Remove right border only if both current and right cell are occupied + ...(isOccupied && rightCellOccupied && { "border-right": "none" }), + // Remove bottom border only if both current and bottom cell are occupied + ...(isOccupied && bottomCellOccupied && { "border-bottom": "none" }), + }; + }; + + // Render grid guides for a specific breakpoint + const renderGridGuides = ( + breakpoint: keyof GridOccupiedAreas, + className: string, + cols: number, + rows: number + ) => ( +