{"id":25021940,"url":"https://github.com/gerzer/sheet-stack","last_synced_at":"2025-10-05T12:36:38.089Z","repository":{"id":194548966,"uuid":"691322310","full_name":"Gerzer/Sheet-Stack","owner":"Gerzer","description":"Easily present SwiftUI sheets from anywhere in your app.","archived":false,"fork":false,"pushed_at":"2023-09-14T01:32:06.000Z","size":13,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-30T11:44:14.608Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Gerzer.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}},"created_at":"2023-09-14T00:23:27.000Z","updated_at":"2023-09-14T01:16:28.000Z","dependencies_parsed_at":"2023-09-14T03:22:10.340Z","dependency_job_id":null,"html_url":"https://github.com/Gerzer/Sheet-Stack","commit_stats":null,"previous_names":["gerzer/sheet-stack"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/Gerzer/Sheet-Stack","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Gerzer%2FSheet-Stack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Gerzer%2FSheet-Stack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Gerzer%2FSheet-Stack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Gerzer%2FSheet-Stack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Gerzer","download_url":"https://codeload.github.com/Gerzer/Sheet-Stack/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Gerzer%2FSheet-Stack/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278457468,"owners_count":25989952,"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-10-05T02:00:06.059Z","response_time":54,"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":[],"created_at":"2025-02-05T13:37:41.233Z","updated_at":"2025-10-05T12:36:38.058Z","avatar_url":"https://github.com/Gerzer.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Sheet Stack\nSheet Stack makes it easy to present sheets from anywhere in your SwiftUI app.\n\n## Provider\nThe first step is to create a provider type that conforms to `SheetPresentationProvider`. This type generates the contents of every sheet that you present. There are two relevant protocol requirements: the `SheetType` associated type and the `content(sheetType:)` method.\n\n### Sheet Type\nA `SheetType` instance identifies a particular type of sheet that your app can present. A great way to implement `SheetType` is to use an enumeration:\n```swift\nstruct MySheetPresentationProvider: SheetPresenationProvider {\n\tenum SheetType: Hashable, Identifiable {\n\t\tcase signIn\n\t\tcase whatsNew\n\t\tcase upsell(featureName: String)\n\t\t…\n\t}\n\t…\n}\n```\n\n`SheetType` must conform to both `Hashable` and `Identifiable`. In many cases, the compiler can synthesize the `Hashable` conformance for you. The easiest way to conform to `Identifiable` is to use `self` as the `id`:\n```swift\nenum SheetType: Hashable, Identifiable {\n\t…\n\tvar id: Self {\n\t\tget {\n\t\t\treturn self\n\t\t}\n\t}\n}\n```\n\n### Content\nThe `content(sheetType:)` method returns the content of a sheet given a sheet type. It’s a view builder, so you can use the standard SwiftUI result-builder syntax to build your views. If you’re using an enumeration to satisfy the `SheetType` requirement, then your `content(sheetType:)` implementation might look something like this:\n```swift\nstruct MySheetPresentationProvider: SheetPresentationProvider {\n\t…\n\tfunc content(sheetType: SheetType) -\u003e some View {\n\t\tswitch sheetType {\n\t\tcase .signIn:\n\t\t\tNavigationView {\n\t\t\t\tSignInView()\n\t\t\t}\n\t\tcase .whatsNew:\n\t\t\tWhatsNewView()\n\t\tcase .upsell(let featureName):\n\t\t\tUpsellView(featureName: featureName)\n\t\t\t\t.interactiveDismissDisabled()\n\t\t}\n\t}\n}\n```\n\n## Sheet Stack\nThe next step is to create a sheet stack. `SheetStack` is generic over the sheet type, so it’s often helpful to declare a type alias to make it easier to spell:\n```swift\ntypealias MySheetStack = SheetStack\u003cMySheetPresentationProvider.SheetType\u003e\n```\n\nIn most cases, you’ll want to use a separate `SheetStack` instance per scene so that pushing a sheet in one scene doesn’t unexpectedly present it in a different scene. You can set your sheet stacks as environment objects like so:\n```swift\nstruct MyApp: App {\n\tstatic let contentViewSheetStack = MySheetStack()\n\tstatic let settingsViewSheetStack = MySheetStack()\n\tvar body: some Scene {\n\t\tWindowGroup {\n\t\t\tContentView()\n\t\t\t\t.environmentObject(Self.contentViewSheetStack)\n\t\t}\n\t\tSettings {\n\t\t\tSettingsView()\n\t\t\t\t.environmentObject(Self.settingsViewSheetStack)\n\t\t}\n\t}\n}\n```\nIn this example, we use the same `SheetStack` specialization (_i.e._, `MySheetStack`) and therefore the same `SheetType` implementation in both scenes. Alternatively, you can use separate `SheetStack` specializations with different `SheetType` implementations if you prefer stronger encapsulation.\n\nSheet stacks are isolated to the main actor to prevent race conditions while adhering to SwiftUI’s requirement that all view updates occur on the main executor.\n\n## Presentation\nTo present your sheets, you need to call the `push(_:)` method on your shared sheet stack. If you set your sheet stack as an environment object, then you can use it like so:\n```swift\nstruct ContentView: View {\n\t@EnvironmentObject private var sheetStack: MySheetStack\n\tvar body: some View {\n\t\tButton(\"Sign In\") {\n\t\t\tself.sheetStack.push(.signIn)\n\t\t}\n\t\t…\n\t}\n}\n```\n\nYou also need to attach the `sheetPresentation(provider:sheetStack:)` view modifier to every root view that can present sheets:\n```swift\nstruct ContentView: View {\n\t…\n\tvar body: some View {\n\t\tButton(\"Sign In\") { … }\n\t\t\t.sheetPresentation(\n\t\t\t\tprovider: MySheetPresentationProvider(),\n\t\t\t\tsheetStack: self.sheetStack\n\t\t\t)\n\t}\n}\n```\n\nYou can present sheets from anywhere in your app, not just views, as long as the currently visible view’s root has a `sheetPresentation(provider:sheetStack:)` modifier.\n\nTo dismiss a sheet, call `pop()`:\n```swift\n…\nself.sheetStack.pop()\n…\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgerzer%2Fsheet-stack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgerzer%2Fsheet-stack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgerzer%2Fsheet-stack/lists"}