{"id":22664690,"url":"https://github.com/zach-klippenstein/constraints-explorer","last_synced_at":"2025-04-06T10:11:10.164Z","repository":{"id":264531949,"uuid":"893156346","full_name":"zach-klippenstein/constraints-explorer","owner":"zach-klippenstein","description":"A lightweight tool to help understand and debug how Compose's layout constraints affect your composables.","archived":false,"fork":false,"pushed_at":"2024-12-02T18:07:43.000Z","size":897,"stargazers_count":120,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-30T09:05:48.821Z","etag":null,"topics":["android","compose","jetpack-compose","ui"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zach-klippenstein.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":"2024-11-23T17:22:00.000Z","updated_at":"2025-03-30T02:43:18.000Z","dependencies_parsed_at":"2024-12-17T18:11:49.606Z","dependency_job_id":"cdfd99cd-6a9b-41d1-b83f-0cb9112f33ec","html_url":"https://github.com/zach-klippenstein/constraints-explorer","commit_stats":null,"previous_names":["zach-klippenstein/constraints-explorer"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zach-klippenstein%2Fconstraints-explorer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zach-klippenstein%2Fconstraints-explorer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zach-klippenstein%2Fconstraints-explorer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zach-klippenstein%2Fconstraints-explorer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zach-klippenstein","download_url":"https://codeload.github.com/zach-klippenstein/constraints-explorer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247464220,"owners_count":20942970,"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":["android","compose","jetpack-compose","ui"],"created_at":"2024-12-09T13:16:37.119Z","updated_at":"2025-04-06T10:11:10.145Z","avatar_url":"https://github.com/zach-klippenstein.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# constraints-explorer [![Maven Central Version](https://img.shields.io/maven-central/v/com.zachklipp/constraints-explorer)](https://central.sonatype.com/artifact/com.zachklipp/constraints-explorer)\n\nA lightweight tool to help understand and debug how Compose's layout constraints affect your\ncomposables. It's intended to use in previews and lets you adjust the constraints interactively:\n\n![demo of constraints explorer](assets/preview-demo.gif)\n\nTo learn more about Compose's layout system and the role of constraints, see the [documentation on\nDeveloper Android](https://developer.android.com/develop/ui/compose/layouts/basics).\n\n## Usage\n\nTo use it, first add the dependency:\n\n```kotlin\nimplementation(\"com.zachklipp:constraints-explorer:{version}\")\n```\n\n_Note that for now, this is an Android-only library, since it's intended to be used with Android\nStudio's preview feature. However, I'm open to making it Compose Multiplatform eventually._\n\nThen, assuming your project has some `@Preview`s, wrap the contents of a preview with the\n`ConstraintsExplorer` composable:\n\n```kotlin\n@Preview\n@Composable\nprivate fun YourComposablePreview() {\n  ConstraintsExplorer {\n    // Your preview code goes here.\n    YourComposable()\n  }\n}\n```\n\nRefresh the preview, and you should see your composable with a gray bar on the top and the right\nof the preview frame, and a label that says “Constraint explorer available”.\n\n![screenshot of non-interactive preview](assets/preview.png)\n\nTo get the interactive preview, simply enter the preview's “Interactive mode” by clicking on this\nbutton:\n\n![screenshot of button to enable interactive mode](assets/preview-interactive-button.png)\n\nThe gray bars around your preview will get some triangles. These represent the minimum and maximum\nconstraints that get passed to your composable's layout. You can drag these triangles around to\nadjust the constraints and see your composable react in real-time.\n\n![screenshot of interactive constraints explorer](assets/preview-interactive.png)\n\nIn interactive mode, the preview will expand to fill the maximum constraints of the preview area.\nThe constraints explorer does not draw anything behind your component. In the above screenshot, the\npreview is configured with a red background to highlight where the actual component bounds are.\n\nBy default, `ConstraintsExplorer` won't do anything when not running in a preview. This probably\nwon't matter if you only use this composable in your `@Preview` functions, but it also means that\nif you're using your previews for tests (e.g. snapshot tests with Paparazzi), it won't show up in\nthose tests. You can override this behavior by passing the `enabled` flag to `ConstraintsExplorer`.\n\n### Unbounded maximum constraints\n\nClicking on a maximum constraint handle will toggle whether that constraint is “unbounded”. An\nunbounded maximum constraint has value `Constraints.Infinity` and is indicated by the arrow being\ndrawn with a dotted outline. Dragging an unbounded handle will re-enable its bound automatically.\n\n![screen recording of toggling unbounded constraint](assets/preview-toggling-unbounded-constraints.gif)\n\n### A note on `fillMax*` modifiers in previews\n\nIf you're passing any size-related modifier to the root composable inside your preview, you might\nwant to move it to `ConstraintsExplorer` instead. It won't affect the static preview and it allows\nthe explorer to actually “explore” more of your component.\n\n\u003e E.g. if you have this:\n\u003e ```kotlin\n\u003e @Preview\n\u003e @Composable\n\u003e private fun YourComposablePreview() {\n\u003e   ConstraintsExplorer {\n\u003e     YourComposable(Modifier.fillMaxSize())\n\u003e   }\n\u003e }\n\u003e ```\n\u003e\n\u003e consider changing it to this:\n\u003e\n\u003e ```kotlin\n\u003e @Preview\n\u003e @Composable\n\u003e private fun YourComposablePreview() {\n\u003e   ConstraintsExplorer(Modifier.fillMaxSize()) {\n\u003e     YourComposable()\n\u003e   }\n\u003e }\n\u003e ```\n\n_If you're just setting the size to an exact size, you can also do that by passing `widthDp` and\n`heightDp` parameters to the `@Preview` annotation itself._\n\nIf you're modifying the size (or more precisely, the constraints) of your composable inside the\n`ConstraintsExplorer`, then when you're playing with the sliders in interactive mode you won't get\nto see how your unmodified component reacts; you'll be seeing how it reacts with the additional\nconstraints modifier. That isn't very useful, since that modifier is only applied in the preview.\n\n`ConstraintsExplorer` will always fill all available space in interactive mode in order to allow you\nto modify the min/max constraints within that space and it doesn't modify the constraints at all in\nnon-interactive mode. So moving size modifiers to `ConstraintsExplorer` won't change the\nnon-interactive preview but allows your component to see and react to the constraints you can adjust\nin interactive mode.\n\nFor example, when you have `fillMaxSize` inside `ConstraintsExplorer`, your composable will ignore\nthe incoming minimum constraints (the arrows pointing right and down), so moving those sliders won't\nhave any effect, and you're not going to see how your unmodified component will actually behave in\nother contexts. If your component itself always fills available space, then this won't make any\ndifference but then using `fillMaxSize` in your preview is redundant anyway.\n\n## Motivation\n\nThis tool was originally written as a companion to an\n[article about centering](https://blog.zachklipp.com/centering-in-compose/).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzach-klippenstein%2Fconstraints-explorer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzach-klippenstein%2Fconstraints-explorer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzach-klippenstein%2Fconstraints-explorer/lists"}