feat(web): Add Grid component

This commit is contained in:
Wanjohi
2025-07-22 15:53:38 +03:00
parent 41b85d6436
commit 7ebf0644f1

View File

@@ -0,0 +1,192 @@
import { splitProps, For } from "solid-js";
import type { ParentProps, JSX } from 'solid-js';
import styles from "./index.module.css";
export interface GridRootProps {
gridRows?: number;
smGridColumns?: number;
mdGridColumns?: number;
lgGridColumns?: number;
smHeight?: string;
heroHeading?: boolean;
class?: string;
style?: JSX.CSSProperties;
}
const defaultProps: GridRootProps = {
gridRows: 1,
lgGridColumns: 1,
mdGridColumns: 1,
heroHeading: false,
smHeight: "calc(var(--width) / var(--grid-cols) * var(--grid-rows))",
smGridColumns: 1,
}
export function Root(props: ParentProps<GridRootProps>) {
const [local, others] = splitProps({ ...defaultProps, ...props }, [
"gridRows",
"smGridColumns",
"mdGridColumns",
"lgGridColumns",
"smHeight",
"heroHeading",
"class",
"style",
"children"
]);
const styleVars: Record<string, string> = {
...(local.smHeight && { "--sm-height": local.smHeight }),
...(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() }),
}
const styleStr = Object.entries({ ...styleVars, ...local.style })
.filter(([, v]) => v !== undefined)
.map(([k, v]) => `${k}: ${v}`)
.join("; ");
return (
<div
class={`${styles.grid_system} ${styles.grid_grid} ${local.heroHeading ? styles.grid_headingGrid : ""} ${local.class || ""}`}
style={styleStr}
{...others}
>
{local.children}
<div class={styles.grid_gridGuides}>
<For each={Array.from({ length: local.gridRows || 1 })}>
{(_, rowIndex) => (
<For each={Array.from({ length: local.smGridColumns || 0 })}>
{(_, colIndex) => (
<div
class={`${styles.grid_gridGuide} ${styles.grid_xsGuide}`}
style={{
"--x": colIndex() + 1,
"--y": rowIndex() + 1,
...(((local.gridRows || 1) > 1 && rowIndex() < (local.gridRows || 1) - 1) && {
"border-bottom-width": "var(--guide-width)"
})
}}
/>
)}
</For>
)}
</For>
</div>
<div class={styles.grid_gridGuides}>
<For each={Array.from({ length: local.gridRows || 1 })}>
{(_, rowIndex) => (
<For each={Array.from({ length: local.smGridColumns || 0 })}>
{(_, colIndex) => (
<div
class={`${styles.grid_gridGuide} ${styles.grid_smGuide}`}
style={{
"--x": colIndex() + 1,
"--y": rowIndex() + 1,
...(((local.gridRows || 1) > 1 && rowIndex() < (local.gridRows || 1) - 1) && {
"border-bottom-width": "var(--guide-width)"
})
}}
/>
)}
</For>
)}
</For>
</div>
<div class={styles.grid_gridGuides}>
<For each={Array.from({ length: local.gridRows || 1 })}>
{(_, rowIndex) => (
<For each={Array.from({ length: local.mdGridColumns || 0 })}>
{(_, colIndex) => (
<div
class={`${styles.grid_gridGuide} ${styles.grid_smdGuide}`}
style={{
"--x": colIndex() + 1,
"--y": rowIndex() + 1,
...(((local.gridRows || 1) > 1 && rowIndex() < (local.gridRows || 1) - 1) && {
"border-bottom-width": "var(--guide-width)"
})
}}
/>
)}
</For>
)}
</For>
</div>
<div class={styles.grid_gridGuides}>
<For each={Array.from({ length: local.gridRows || 1 })}>
{(_, rowIndex) => (
<For each={Array.from({ length: local.mdGridColumns || 1 })}>
{(_, colIndex) => (
<div
class={`${styles.grid_gridGuide} ${styles.grid_mdGuide}`}
style={{
"--x": colIndex() + 1,
"--y": rowIndex() + 1,
...(((local.gridRows || 1) > 1 && rowIndex() < (local.gridRows || 1) - 1) && {
"border-bottom-width": "var(--guide-width)"
})
}}
/>
)}
</For>
)}
</For>
</div>
<div class={styles.grid_gridGuides}>
<For each={Array.from({ length: local.gridRows || 1 })}>
{(_, rowIndex) => (
<For each={Array.from({ length: local.lgGridColumns || 0 })}>
{(_, colIndex) => (
<div
class={`${styles.grid_gridGuide} ${styles.grid_lgGuide}`}
style={{
"--x": colIndex() + 1,
"--y": rowIndex() + 1,
...(((local.gridRows || 1) > 1 && rowIndex() < (local.gridRows || 1) - 1) && {
"border-bottom-width": "var(--guide-width)"
})
}}
/>
)}
</For>
)}
</For>
</div>
</div>
);
}
interface GridCrossProps {
crossRow: number;
crossColumn: number;
}
export function Cross(props: GridCrossProps) {
return (
<div style={{
"--cross-row": props.crossRow,
"--cross-column": props.crossColumn,
}} class={styles.grid_cross}>
<div
style={{
"border-right-width": "var(--guide-width)",
"width": "var(--cross-half-size)",
"height": "var(--cross-size)"
}}
class={styles.grid_crossLine} />
<div
style={{
"border-bottom-width": "var(--guide-width)",
"width": "var(--cross-size)",
"height": "var(--cross-half-size)"
}}
class={styles.grid_crossLine} />
</div>
)
}
export default { Cross, Root }