{"id":13551034,"url":"https://github.com/shyndman/flutter_layout_grid","last_synced_at":"2025-04-03T01:31:03.672Z","repository":{"id":36056269,"uuid":"221119070","full_name":"shyndman/flutter_layout_grid","owner":"shyndman","description":"A grid-based layout system for Flutter, inspired by CSS Grid Layout","archived":false,"fork":false,"pushed_at":"2024-05-20T03:23:25.000Z","size":1429,"stargazers_count":448,"open_issues_count":22,"forks_count":44,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-04-02T01:35:48.492Z","etag":null,"topics":["dart","flutter","grid-layout","layout"],"latest_commit_sha":null,"homepage":"","language":"Dart","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/shyndman.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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}},"created_at":"2019-11-12T03:09:46.000Z","updated_at":"2025-03-24T08:13:36.000Z","dependencies_parsed_at":"2024-05-20T04:29:14.217Z","dependency_job_id":"f0a76f8a-6238-4a7f-b076-c3e453900790","html_url":"https://github.com/shyndman/flutter_layout_grid","commit_stats":null,"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shyndman%2Fflutter_layout_grid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shyndman%2Fflutter_layout_grid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shyndman%2Fflutter_layout_grid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shyndman%2Fflutter_layout_grid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shyndman","download_url":"https://codeload.github.com/shyndman/flutter_layout_grid/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246922022,"owners_count":20855341,"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","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":["dart","flutter","grid-layout","layout"],"created_at":"2024-08-01T12:01:41.465Z","updated_at":"2025-04-03T01:31:00.491Z","avatar_url":"https://github.com/shyndman.png","language":"Dart","funding_links":[],"categories":["Dart"],"sub_categories":[],"readme":"# Flutter Layout Grid\n\n[![Pub](https://img.shields.io/pub/v/flutter_layout_grid)](https://pub.dev/packages/flutter_layout_grid)\n[![Github test](https://github.com/shyndman/flutter_layout_grid/workflows/test/badge.svg)](https://github.com/shyndman/flutter_layout_grid/actions?query=workflow%3Atest)\n\nA powerful grid layout system for Flutter, optimized for complex user interface\ndesign.\n\n\u003ca href=\"https://github.com/shyndman/flutter_layout_grid/tree/main/example/lib/flutter_layout_grid_example.dart\"\u003e\n  \u003cimg\n    src=\"https://raw.githubusercontent.com/shyndman/flutter_layout_grid/master/doc/images/piet_trimmed.png\"\n    alt=\"Piet painting recreated using Flutter Layout Grid\" height=\"220\"\u003e\n\u003c/a\u003e\n\u0026nbsp;\n\n\u003ca href=\"https://github.com/shyndman/flutter_layout_grid/tree/main/example/lib/periodic_table.dart\"\u003e\n  \u003cimg\n    src=\"https://raw.githubusercontent.com/shyndman/flutter_layout_grid/main/doc/images/periodic_table.png\"\n    alt=\"Periodic table rendered using Flutter Layout Grid\" height=\"220\"\u003e\n\u003c/a\u003e\n\u0026nbsp;\n\n\u003ca href=\"https://github.com/shyndman/flutter_layout_grid/tree/main/example/lib/scrabble.dart\"\u003e\n\u003cimg\n    src=\"https://raw.githubusercontent.com/shyndman/flutter_layout_grid/master/doc/images/scrabble.png\"\n    alt=\"Scrabble board rendered using Flutter Layout Grid\" height=\"330\"\u003e\n\u003c/a\u003e\n\n_Click images to see their code_\n\n---\n\n✨Featuring:✨\n\n- 📐 Fixed, flexible, and content-sized rows and columns\n  ([docs](#sizing-of-columns-and-rows))\n- 👇 Precise control over placement of items, including the ability to span\n  rows, columns, and overlap items\n  ([docs](#positioning-child-widgets-in-the-layoutgrid))\n- 💬 Named grid areas for descriptive positioning of children\n  ([docs](#naming-areas-of-the-grid))\n- 🦾 A configurable automatic grid item placement algorithm, capable of sparse\n  and dense packing across rows and columns ([docs](#automatic-child-placement))\n- 🔚 Right-to-left support, driven by ambient `Directionality` or configuration\n- ♿ Accessibility considerations (**this is your responsibility** as a frontend\n  developer, so please read [docs](#accessibility-and-placement) and learn\n  related technologies)\n- 🩳 Extension methods and helper functions for descriptive, and short, layout\n  code\n- 🐛 Debugging aids, including widget property listings in\n  [DevTools](https://flutter.dev/docs/development/tools/devtools/overview),\n  Debug Painting, and visual indication of child overflow\n\nInspired by (and largely based on), the excellent [CSS Grid\nLayout](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout) spec.\n\n## Getting Started\n\nAll the terminology used in this library is shared with the CSS Grid Layout\nspec. If youʼre unfamiliar, I recommend taking a look at [MDNʼs glossary of grid\nterms](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout#Glossary_entries).\n\nFor inclusion in your pubspec, see\n[pub.dev](https://pub.dev/packages/flutter_layout_grid/install), or copy\nthe code below:\n\n```yaml\ndependencies:\n  flutter_layout_grid: ^2.0.0\n```\n\n## Example\n\n#### Visual:\n\n\u003ca href=\"https://github.com/shyndman/flutter_layout_grid/tree/main/example/lib/app_layout.dart\"\u003e\n  \u003cimg\n    src=\"https://raw.githubusercontent.com/shyndman/flutter_layout_grid/master/doc/images/app_layout.png\"\n    alt=\"Desktop app layout rendered using Flutter Layout Grid\" height=\"220\"\u003e\n\u003c/a\u003e\n\n#### Code:\n\n```dart\nimport 'package:flutter_layout_grid/flutter_layout_grid.dart';\n\nclass App extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Container(\n      color: background,\n      child: LayoutGrid(\n        // ASCII-art named areas 🔥\n        areas: '''\n          header header  header\n          nav    content aside\n          nav    content .\n          footer footer  footer\n        ''',\n        // Concise track sizing extension methods 🔥\n        columnSizes: [152.px, 1.fr, 152.px],\n        rowSizes: [\n          112.px,\n          auto,\n          1.fr,\n          64.px,\n        ],\n        // Column and row gaps! 🔥\n        columnGap: 12,\n        rowGap: 12,\n        // Handy grid placement extension methods on Widget 🔥\n        children: [\n          Header().inGridArea('header'),\n          Navigation().inGridArea('nav'),\n          Content().inGridArea('content'),\n          Aside().inGridArea('aside'),\n          Footer().inGridArea('footer'),\n        ],\n      ),\n    );\n  }\n}\n```\n\nThis example is available at\n[`example/app_layout.dart`](https://github.com/shyndman/flutter_layout_grid/tree/main/example/lib/app_layout.dart).\n\nFor a similar example that includes responsive behavior, check out\n[`example/responsive_app_layout.dart`](https://github.com/shyndman/flutter_layout_grid/tree/main/example/lib/responsive_app_layout.dart).\n\n## Sizing of Columns and Rows\n\nThe sizes of the gridʼs columns and rows are set using\n`LayoutGrid.columnSizes` and `LayoutGrid.rowSizes`.\n\nHereʼs what a 4⨉3 grid might look like (4 columns, 3 rows):\n\n```dart\nLayoutGrid(\n  columnSizes: [4.5.fr, 100.px, auto, 1.fr],\n  rowSizes: [\n    auto,\n    100.px,\n    1.fr,\n  ],\n)\n```\n\nEach element of `columnSizes` and `rowSizes` represents the function used to\nsize a column or row (collectively known as **\"track sizes\"**).\n\nThere are currently three way to size rows and columns:\n\n| Class Name                  | Description                                                                                                                                      | Usage                                                    |\n| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------- |\n| `FixedTrackSize`            | Occupies a specific number of pixels on an axis                                                                                                  | `FixedTrackSize(64)`\u003cbr\u003e`fixed(64)`\u003cbr\u003e`64.px`           |\n| `FlexibleSizeTrack`         | Fills remaining space after the initial layout has completed                                                                                     | `FlexibleTrackSize(1.5)`\u003cbr\u003e`flexible(1.5)`\u003cbr\u003e`1.5.fr`  |\n| `IntrinsicContentTrackSize` | Sized to contain its itemsʼ contents. Will also expand to fill available space, once `FlexibleTrackSize` tracks have been given the opportunity. | `IntrinsicContentTrackSize()`\u003cbr\u003e`intrinsic()`\u003cbr\u003e`auto` |\n\nTechnically, you can also define your own, but probably shouldnʼt as the API\nwill likely be evolving as I tackle\n([#25](https://github.com/shyndman/flutter_layout_grid/issues/25))\n([`minmax()`](https://developer.mozilla.org/en-US/docs/Web/CSS/minmax)\nsupport).\n\n## Naming areas of the grid\n\nA gridʼs rows and columns can be sliced into areas — rectangular regions\ncontaining one or more grid cells. These areas can be named (_optionally_), and\nused to place gridʼs children. The areas are named using an ASCII-art string\nprovided to the `areas` parameter.\n\n```dart\nLayoutGrid(\n  areas: '''\n    header header\n    nav    content\n    footer footer\n  ''',\n  // ...\n)\n```\n\n\u003e Note: We use the same format as CSSʼs\n\u003e [`grid-template-areas`](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-areas),\n\u003e except we use a multiline string.\n\nIf an `areas` argument has been provided to a grid, you must specify the same\nnumber of sizes using `columnSizes` and `rowSizes` elements. For the example\nabove:\n\n```dart\nLayoutGrid(\n  areas: '''\n    header header\n    nav    content\n    footer footer\n  ''',\n  // 2 columns, 3 rows, just like the areas string\n  columnSizes: [\n    auto, // contributes width to [nav, header, footer]\n    1.fr, // contributes width to [content, header, footer]\n  ],\n  rowSizes: [\n    96.px, // contributes height to [header]\n    1.fr,  // contributes height to [nav, content]\n    72.px, // contributes height to [footer]\n  ],\n  children: [\n    // ...\n  ],\n)\n```\n\nGrid children can be assigned to named areas using the `NamedAreaGridPlacement`\nwidget. For more information, see [assigning the child to a named\narea](#child-placement-in-named-areas).\n\n## Positioning child widgets in the `LayoutGrid`\n\nOnce you have a grid, you have to tell its `children` which rows and columns\nthey should occupy. There are three ways of doing this:\n\n- [Specifying row and column indexes](#child-placement-by-row-and-column-indexes)\n- [Assigning the child to a named area](#child-placement-in-named-areas)\n- [Using automatic placement](#automatic-child-placement)\n\n### Child placement by row and column indexes\n\nA gridʼs child can be instructed to occupy a specific set of columns and rows\nby using the `GridPlacement` widget.\n\nFor example, letʼs say you had a 4⨉3 grid, and you wanted a widget to be\npositioned from column 1–4 and row 0–2:\n\n```dart\nLayoutGrid(\n  columnSizes: [1.fr, 1.fr, 1.fr, 1.fr],\n  rowSizes: [\n    1.fr,\n    1.fr,\n    1.fr,\n  ],\n  children: [\n    GridPlacement(\n      columnStart: 1,\n      columnSpan: 3,\n      rowStart: 0,\n      rowSpan: 2,\n      child: MyWidget(),\n    ),\n    // Alternatively, an extension method on Widget is available\n    MyWidget().withGridPlacement(\n      columnStart: 1,\n      columnSpan: 3,\n      rowStart: 0,\n      rowSpan: 2,\n    ),\n  ],\n)\n```\n\n`GridPlacement` also has a super power — all of its parameters are optional.\nIf, for example, you do not specify a `rowStart`, the [automatic placement\nalgorithm](#automatic-child-placement) will attempt to place the child in the\nfirst vacant spot that it can find.\n\n### Child placement in named areas\n\nIf your grid has [named areas](#naming-areas-of-the-grid) defined, you can\nplace children in those areas using the `NamedAreaGridPlacement` widget. For\nexample:\n\n```dart\nLayoutGrid(\n  areas: '''\n    red red blue\n    red red blue\n     .   .  blue\n  ''',\n  // Note that the number of columns and rows matches the grid above (3x3)\n  columnSizes: [64.px, 64.px, 64.px],\n  rowSizes: [\n    64.px,\n    64.px,\n    64.px,\n  ],\n  children: [\n    // Using NamedAreaGridPlacement constructor\n    NamedAreaGridPlacement(\n      areaName: 'red',\n      child: Container(color: Colors.red),\n    ),\n    // Alternatively, an extension method on Widget is available\n    Container(color: Colors.red).inGridArea('red'),\n  ],\n)\n```\n\n**NOTE:** If a `NamedAreaGridPlacement` references a named area that doesnʼt\nexist, it will not be displayed in the grid. This can be helpful when switching\nbetween responsive layouts.\n\n### Automatic child placement\n\nGrid children can be placed into rows and columns automatically based on partial\nor non-existent placement information.\n\nThe algorithm responsible for automatic placement has several modes, selected\nthrough the `LayoutGrid.autoPlacement` parameter. The behavior of these modes\nare identical to those supported by CSSʼs grid, described [described\nhere](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Auto-placement_in_CSS_Grid_Layout).\n\n#### When no placement information is provided\n\nIf a child is provided to the grid without being wrapped in a `GridPlacement` or\n`NamedAreaGridPlacement`, it will be allotted a single cell (1⨉1), and placed\ninto the first vacant cell in the grid.\n\n#### When partial placement information is provided\n\nAll of the `GridPlacement` widgetʼs parameters are optional. By specifying\nadditional positioning or spanning information with\n`columnStart`/`columnSpan`/`rowStart`/`rowSpan` parameters, more\nconstraints are fed into the placement algorithm.\n\nFor example, if `columnStart` is provided, but not `rowStart`, the placement\nalgorithm will walk across the gridʼs rows until it finds a vacant area, in the\nspecified column, that accommodates the child.\n\n[Read more about CSSʼs grid placement\nalgorithm](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Auto-placement_in_CSS_Grid_Layout)\n\n### Accessibility and Placement\n\nTake note that the meaning you convey visually through placement may not be\nclear when presented by assitive technologies, as Flutter defaults to exposing\ninformation in source order.\n\nIn situations where your semantic (visual) ordering differs from ordering in the\nsource, the ordering can be configured via the `Semantics` widgetʼs\n[`sortKey`](https://api.flutter.dev/flutter/semantics/SemanticsSortKey-class.html)\nparameter.\n\nFor an example of this in practice, see\n[example/semantic_ordering.dart](https://github.com/shyndman/flutter_layout_grid/tree/main/example/lib/semantic_ordering.dart).\n\nAutomatic semantic ordering is currently being explored in\n[#50](https://github.com/shyndman/flutter_layout_grid/issues/50).\n\n## Differences from CSS Grid Layout\n\nThings in CSS Grid Layout that are not supported:\n\n- Negative row/column starts/ends. In CSS, these values refer to positions\n  relative to the end of a gridʼs axis. Handy, but weʼre not there yet.\n  ([#5](https://github.com/shyndman/flutter_layout_grid/issues/5))\n- Any cells outside of the explicit grid. If an item is placed outside of the\n  area defined by your template rows/columns, we will throw an error. Support\n  for automatic addition of rows and columns to accommodate out of bound items\n  is being considered.\n  ([#7](https://github.com/shyndman/flutter_layout_grid/issues/7))\n- minmax(), percentages, aspect ratios track sizing\n  ([#25](https://github.com/shyndman/flutter_layout_grid/issues/25))\n\nDifferences:\n\n- In `flutter_layout_grid`, flexible tracks do not account for their contentʼs\n  base sizes as they do in CSS. Itʼs expensive to measure, and I opted for\n  speed.\n- Flexible tracks whose flex factors sum to \u003c 1\n\n## Roadmap\n\n- [x] Tests! (we now have a decent suite going)\n- [x] Named template areas, for friendlier item placement\n- [ ] Improved track sizing, including minimum/maximums and aspect ratios\n- [ ] The ability to specify row and column gaps at specific line locations via\n      a delegate\n- [ ] Implicit grid support (automatic growth along an axis as children are\n      added)\n- [x] Performance improvements, as soon as I can get this profiler running(!!!)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshyndman%2Fflutter_layout_grid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshyndman%2Fflutter_layout_grid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshyndman%2Fflutter_layout_grid/lists"}