{"id":31391722,"url":"https://github.com/tscircuit/minicssgrid","last_synced_at":"2025-09-29T02:55:21.878Z","repository":{"id":307012404,"uuid":"1027946027","full_name":"tscircuit/minicssgrid","owner":"tscircuit","description":"A tiny CSS grid implementation in typescript","archived":false,"fork":false,"pushed_at":"2025-08-29T19:58:31.000Z","size":264,"stargazers_count":66,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-16T04:50:31.594Z","etag":null,"topics":["css-grid","css-grid-layout","tscircuit"],"latest_commit_sha":null,"homepage":"https://minigrid.tscircuit.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tscircuit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-28T19:20:09.000Z","updated_at":"2025-08-29T19:58:34.000Z","dependencies_parsed_at":"2025-08-21T06:31:59.230Z","dependency_job_id":null,"html_url":"https://github.com/tscircuit/minicssgrid","commit_stats":null,"previous_names":["tscircuit/minigrid","tscircuit/minicssgrid"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tscircuit/minicssgrid","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tscircuit%2Fminicssgrid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tscircuit%2Fminicssgrid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tscircuit%2Fminicssgrid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tscircuit%2Fminicssgrid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tscircuit","download_url":"https://codeload.github.com/tscircuit/minicssgrid/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tscircuit%2Fminicssgrid/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275756267,"owners_count":25522773,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-18T02:00:09.552Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["css-grid","css-grid-layout","tscircuit"],"created_at":"2025-09-29T02:55:20.339Z","updated_at":"2025-09-29T02:55:21.870Z","avatar_url":"https://github.com/tscircuit.png","language":"TypeScript","readme":"# minicssgrid\n\nA tiny CSS grid implementation in TypeScript that provides programmatic CSS Grid layout computation.\n\n[Online Playground](https://minigrid.tscircuit.com)\n\n\u003cimg width=\"250\" height=\"250\" alt=\"image\" src=\"https://github.com/user-attachments/assets/c0cd5c34-a62c-40e4-b132-fc2f81b6fc49\" /\u003e\n\n## Installation\n\n```bash\nbun add minicssgrid\n# or\nnpm install minicssgrid\n```\n\n## Quick Start\n\n```typescript\nimport { CssGrid } from \"minicssgrid\"\n\n// Create a simple 2x2 grid\nconst grid = new CssGrid({\n  containerWidth: 200,\n  containerHeight: 200,\n  gridTemplateColumns: \"1fr 1fr\",\n  gridTemplateRows: \"1fr 1fr\",\n  children: [\n    { key: \"item1\" },\n    { key: \"item2\" },\n    { key: \"item3\" },\n    { key: \"item4\" },\n  ],\n})\n\n// Get computed layout\nconst { cells, itemCoordinates } = grid.layout()\nconsole.log(itemCoordinates)\n// Output: {\n//   item1: { x: 0, y: 0, width: 100, height: 100 },\n//   item2: { x: 100, y: 0, width: 100, height: 100 },\n//   item3: { x: 0, y: 100, width: 100, height: 100 },\n//   item4: { x: 100, y: 100, width: 100, height: 100 }\n// }\n```\n\n## API Reference\n\n### CssGrid Class\n\nThe main class for creating and computing CSS Grid layouts.\n\n```typescript\nconst grid = new CssGrid(options: CssGridOptions)\n```\n\n#### Methods\n\n- **`layout()`** - Returns computed layout with cell positions and coordinates\n- **`convertToHtml()`** - Generates HTML representation of the grid\n- **`visualize()`** - Returns graphics object for debugging visualization\n\n### CssGridOptions Interface\n\nConfiguration object for the grid container and its items.\n\n```typescript\ninterface CssGridOptions {\n  children: GridItem[] // Grid items to layout\n  gridTemplateRows?: GridTemplate // Row track definitions\n  gridTemplateColumns?: GridTemplate // Column track definitions\n  gap?: number | [number, number] // Gap between grid items\n  justifyItems?: \"start\" | \"end\" | \"center\" | \"stretch\"\n  alignItems?: \"start\" | \"end\" | \"center\" | \"stretch\"\n  containerWidth?: number // Container dimensions\n  containerHeight?: number\n}\n```\n\n### GridItem Interface\n\nIndividual grid item configuration.\n\n```typescript\ninterface GridItem {\n  key: string // Unique identifier\n\n  // Positioning (1-based like CSS Grid)\n  row?: number | string\n  column?: number | string\n  rowSpan?: number | string\n  columnSpan?: number | string\n  rowStart?: number | string\n  columnStart?: number | string\n  rowEnd?: number | string\n  columnEnd?: number | string\n\n  // Content sizing\n  contentWidth?: number | string\n  contentHeight?: number | string\n\n  // Other properties\n  area?: string // Named grid area\n  order?: number | string // Display order\n  payload?: unknown // Custom data\n}\n```\n\n## Grid Templates\n\nGrid templates can be defined as strings (CSS-like) or structured arrays:\n\n### String Format\n\n```typescript\ngridTemplateColumns: \"100px 1fr 2fr\"\ngridTemplateRows: \"repeat(3, 1fr)\"\ngridTemplateColumns: \"20% 20% 20% 20% 20%\"\n```\n\n### Array Format\n\n```typescript\ngridTemplateColumns: [\"100px\", \"1fr\", \"2fr\"]\ngridTemplateRows: [\"repeat(3, 1fr)\"]\n```\n\n### Supported Track Sizes\n\n- **Fixed**: `\"100px\"`, `\"50%\"`\n- **Flexible**: `\"1fr\"`, `\"2fr\"`\n- **Keywords**: `\"auto\"`, `\"min-content\"`, `\"max-content\"`\n- **Functions**: `\"minmax(100px, 1fr)\"`, `\"repeat(3, 1fr)\"`\n\n## Usage Examples\n\n### Basic Grid Layout\n\n```typescript\nconst grid = new CssGrid({\n  containerWidth: 300,\n  containerHeight: 200,\n  gridTemplateColumns: \"1fr 1fr 1fr\",\n  gridTemplateRows: \"1fr 1fr\",\n  children: [\n    { key: \"header\" },\n    { key: \"nav\" },\n    { key: \"main\" },\n    { key: \"aside\" },\n    { key: \"footer\" },\n  ],\n})\n```\n\n### Explicit Item Placement\n\n```typescript\nconst grid = new CssGrid({\n  containerWidth: 400,\n  containerHeight: 300,\n  gridTemplateColumns: \"repeat(4, 1fr)\",\n  gridTemplateRows: \"repeat(3, 1fr)\",\n  children: [\n    { key: \"header\", columnStart: 1, columnEnd: 5, row: 1 },\n    { key: \"sidebar\", column: 1, rowStart: 2, rowEnd: 4 },\n    { key: \"content\", columnStart: 2, columnEnd: 5, rowStart: 2, rowEnd: 4 },\n  ],\n})\n```\n\n### Grid with Spanning Items\n\n```typescript\nconst grid = new CssGrid({\n  containerWidth: 300,\n  containerHeight: 300,\n  gridTemplateColumns: \"1fr 2fr\",\n  gridTemplateRows: \"50px 1fr 50px\",\n  children: [\n    { key: \"header\", columnSpan: 2 }, // Spans 2 columns\n    { key: \"sidebar\" }, // Auto-placed\n    { key: \"content\" }, // Auto-placed\n    { key: \"footer\", columnSpan: 2 }, // Spans 2 columns\n  ],\n})\n```\n\n### Grid with Gaps\n\n```typescript\nconst grid = new CssGrid({\n  containerWidth: 240,\n  containerHeight: 240,\n  gridTemplateColumns: \"1fr 1fr\",\n  gridTemplateRows: \"1fr 1fr\",\n  gap: 20, // 20px gap between items\n  children: [\n    { key: \"box1\" },\n    { key: \"box2\" },\n    { key: \"box3\" },\n    { key: \"box4\" },\n  ],\n})\n```\n\n### Different Gap Values\n\n```typescript\nconst grid = new CssGrid({\n  gridTemplateColumns: \"1fr 1fr 1fr\",\n  gridTemplateRows: \"1fr 1fr\",\n  gap: [10, 20], // [rowGap, columnGap]\n  children: [\n    /* ... */\n  ],\n})\n```\n\n### Item Ordering\n\n```typescript\nconst grid = new CssGrid({\n  containerWidth: 400,\n  containerHeight: 100,\n  gridTemplateColumns: \"1fr 1fr 1fr 1fr\",\n  gridTemplateRows: \"1fr\",\n  children: [\n    { key: \"first\", order: 3 }, // Appears third\n    { key: \"second\", order: 1 }, // Appears first\n    { key: \"third\", order: 2 }, // Appears second\n    { key: \"fourth\" }, // Default order (0), appears last\n  ],\n})\n```\n\n### Content Sizing\n\n```typescript\nconst grid = new CssGrid({\n  gridTemplateColumns: \"auto 1fr auto\",\n  children: [\n    { key: \"icon\", contentWidth: 24, contentHeight: 24 },\n    { key: \"text\", contentWidth: 200 },\n    { key: \"button\", contentWidth: 80, contentHeight: 32 },\n  ],\n})\n```\n\n### Alignment\n\n```typescript\nconst grid = new CssGrid({\n  gridTemplateColumns: \"1fr 1fr\",\n  gridTemplateRows: \"1fr 1fr\",\n  justifyItems: \"center\", // Horizontal alignment\n  alignItems: \"start\", // Vertical alignment\n  children: [\n    /* ... */\n  ],\n})\n```\n\n## Working with Layout Results\n\nThe `layout()` method returns detailed information about the computed grid:\n\n```typescript\nconst { cells, rowSizes, columnSizes, rowGap, columnGap, itemCoordinates } =\n  grid.layout()\n\n// Individual cell information\ncells.forEach((cell) =\u003e {\n  console.log(`${cell.key}: row ${cell.row}, col ${cell.column}`)\n  console.log(`Position: (${cell.x}, ${cell.y})`)\n  console.log(`Size: ${cell.width} × ${cell.height}`)\n  console.log(`Spans: ${cell.rowSpan} rows, ${cell.columnSpan} columns`)\n})\n\n// Quick access to item coordinates\nconst headerCoords = itemCoordinates.header\n// { x: 0, y: 0, width: 300, height: 50 }\n\n// Track information\nconsole.log(\"Column widths:\", columnSizes) // [100, 200, 100]\nconsole.log(\"Row heights:\", rowSizes) // [50, 200, 50]\n```\n\n## HTML Generation\n\nGenerate HTML representation of your grid:\n\n```typescript\nconst htmlString = grid.convertToHtml()\nconsole.log(htmlString)\n```\n\nThis creates a `\u003cdiv\u003e` with CSS Grid styles and child elements positioned accordingly.\n\n## Development \u0026 Testing\n\n### Running Tests\n\n```bash\nbun test                    # Run all tests\nbun test level01           # Run specific test\n```\n\n### Adding Test Cases\n\n## Introducing Test Cases\n\n1. Create a test case in `testcases/levelXX.ts`\n2. Generate the browser result by running `bun run generate-browser-results`\n3. Create a test in `tests/levelXX.test.ts` with the following structure:\n4. Run `bun test tests/levelXX.test.ts -u` to see the test results and update the snapshots\n\n```tsx\nimport { expect, test } from \"bun:test\"\nimport levelXX from \"testcases/levelXX\"\nimport browserResult from \"testcases/levelXX.browser-result.json\"\nimport { testGrid } from \"./fixtures/testGrid\"\n\ntest(\"levelXX\", () =\u003e {\n  const { laidOutResult, outputViz, layout } = testGrid(levelXX, browserResult)\n\n  expect(browserResult).toMatchInlineSnapshot()\n  expect(laidOutResult).toMatchInlineSnapshot()\n\n  expect(layout).toMatchInlineSnapshot()\n  expect(outputViz).toMatchSvgSnapshot(import.meta.path)\n\n  if (!process.env.BUN_UPDATE_SNAPSHOTS) {\n    expect(laidOutResult).toEqual(browserResult)\n  }\n})\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftscircuit%2Fminicssgrid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftscircuit%2Fminicssgrid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftscircuit%2Fminicssgrid/lists"}