Skip to content

Add TryShowPopupAsync and TryClosePopupAsync#3244

Draft
TheCodeTraveler wants to merge 8 commits into
mainfrom
Add-TryShowPopup-and-TryClosePopup
Draft

Add TryShowPopupAsync and TryClosePopupAsync#3244
TheCodeTraveler wants to merge 8 commits into
mainfrom
Add-TryShowPopup-and-TryClosePopup

Conversation

@TheCodeTraveler

Copy link
Copy Markdown
Collaborator

Description of Change

As discussed in the June 2026 Standup, this Pull Request implements TryShowPopupAsync and TryClosePopupAsync.

This PR also adds IResult to standardize the Try/Result pattern across FileSaverResult, FolderPickerResult, ShowPopupResult and ClosePopupResult.

PR Checklist

  • Has a linked Issue, and the Issue has been approved(bug) or Championed (feature/proposal)
  • Has tests (if omitted, state reason in description)
  • Has samples (if omitted, state reason in description)
  • Rebased on top of main at time of PR
  • Changes adhere to coding standard
  • Documentation created or updated: https://github.com/MicrosoftDocs/CommunityToolkit/pulls

Additional information

There is a breaking change in this PR: I removed the CommunityToolkit.Maui.Core.Primitives namespace. This should've never existed; Folder had been using the incorrect namespace.

@TheCodeTraveler TheCodeTraveler added pending documentation This feature requires documentation breaking change This label is used for PRs that include a breaking change labels Jun 18, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a standardized Try/Result pattern for popups (and aligns it with existing storage results) by introducing TryShowPopupAsync / TryClosePopupAsync APIs and a shared IResult interface. It also moves Folder into the CommunityToolkit.Maui.Core namespace (breaking change).

Changes:

  • Add TryShowPopupAsync and TryClosePopupAsync extension methods returning IShowPopupResult(*) / IClosePopupResult(*) with standardized IResult semantics.
  • Introduce IResult and apply it across FileSaverResult, FolderPickerResult, and new popup result types.
  • Move Folder from CommunityToolkit.Maui.Core.Primitives to CommunityToolkit.Maui.Core.

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/CommunityToolkit.Maui/Views/Popup/PopupPage.shared.cs Minor argument validation cleanup for shellRoute.
src/CommunityToolkit.Maui/Primitives/ShowPopupResult.shared.cs Adds concrete result types implementing IShowPopupResult(*).
src/CommunityToolkit.Maui/Primitives/PopupResult.shared.cs Makes PopupResult<T> inheritable to support new result wrappers; formats exception message.
src/CommunityToolkit.Maui/Primitives/ClosePopupResult.cs Adds concrete result types implementing IClosePopupResult(*).
src/CommunityToolkit.Maui/Extensions/PopupExtensions.shared.cs Adds TryShowPopupAsync / TryClosePopupAsync APIs and refactors some internal calls.
src/CommunityToolkit.Maui.UnitTests/Views/Popup/PopupTests.cs Adds test for typed popup completion via CloseAsync(result).
src/CommunityToolkit.Maui.UnitTests/Views/Popup/PopupResultTests.cs Adds unit tests validating default IResult behavior.
src/CommunityToolkit.Maui.UnitTests/Views/Popup/PopupPageTests.cs Adds tests for Shell argument validation and query attribute forwarding edge cases.
src/CommunityToolkit.Maui.UnitTests/Services/PopupServiceTests.cs Adds additional constructor and cancellation behavior tests.
src/CommunityToolkit.Maui.UnitTests/Mocks/FolderPickerImplementationMock.cs Updates namespace import for Folder move.
src/CommunityToolkit.Maui.UnitTests/Extensions/PopupExtensionsTests.cs Adds extensive coverage for new Try* popup APIs across Page/INavigation/Shell.
src/CommunityToolkit.Maui.UnitTests/Essentials/FolderPickerTests.cs Adds IResult semantics tests for FolderPickerResult.
src/CommunityToolkit.Maui.UnitTests/Essentials/FileSaverTests.cs Adds IResult semantics tests for FileSaverResult.
src/CommunityToolkit.Maui.Core/Primitives/Folder.shared.cs Moves Folder into CommunityToolkit.Maui.Core namespace (breaking).
src/CommunityToolkit.Maui.Core/Interfaces/IShowPopupResult.cs Introduces IShowPopupResult(*) interfaces combining IPopupResult(*) + IResult.
src/CommunityToolkit.Maui.Core/Interfaces/IResult.shared.cs Introduces standardized IResult interface with default implementations.
src/CommunityToolkit.Maui.Core/Interfaces/IClosePopupResult.cs Introduces IClosePopupResult(*) interfaces combining IPopupResult(*) + IResult.
src/CommunityToolkit.Maui.Core/Essentials/FolderPicker/FolderPickerResult.shared.cs Implements IResult on FolderPickerResult.
src/CommunityToolkit.Maui.Core/Essentials/FolderPicker/FolderPickerImplementation.windows.cs Updates namespace import for Folder move.
src/CommunityToolkit.Maui.Core/Essentials/FolderPicker/FolderPickerImplementation.net.cs Updates namespace import for Folder move.
src/CommunityToolkit.Maui.Core/Essentials/FolderPicker/FolderPickerImplementation.macios.cs Updates namespace import for Folder move.
src/CommunityToolkit.Maui.Core/Essentials/FolderPicker/FolderPickerImplementation.android.cs Updates namespace import for Folder move.
src/CommunityToolkit.Maui.Core/Essentials/FileSaver/FileSaverResult.shared.cs Implements IResult on FileSaverResult.

Comment thread src/CommunityToolkit.Maui/Extensions/PopupExtensions.shared.cs Outdated
Comment thread src/CommunityToolkit.Maui/Extensions/PopupExtensions.shared.cs
Comment thread src/CommunityToolkit.Maui/Extensions/PopupExtensions.shared.cs
Comment thread src/CommunityToolkit.Maui.Core/Primitives/Folder.shared.cs
Comment thread src/CommunityToolkit.Maui.Core/Primitives/Folder.shared.cs
namespace CommunityToolkit.Maui;

/// <inheritdoc cref="IClosePopupResult" />
record ClosePopupResult(bool WasDismissedByTappingOutsideOfPopup, Exception? Exception)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ClosePopupResult and PopupResult as for me technically the same. We can't get result from not closed Popup. I suggest keeping only PopupResult

/// </summary>
/// <param name="WasDismissedByTappingOutsideOfPopup">True if Popup is closed by tapping outside popup</param>
/// <param name="Exception">Exception if operation failed</param>
record ShowPopupResult(bool WasDismissedByTappingOutsideOfPopup, Exception? Exception) : PopupResult(WasDismissedByTappingOutsideOfPopup), IShowPopupResult;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same here. ShowPopupResult sounds like result that is returned right after Popup is shown. And in that case WasDismissedByTappingOutsideOfPopup is not relevant.

/// <summary>
/// Closes the most recent popup and returns an <see cref="IClosePopupResult"/> that provides details about the closure.
/// </summary>
public static async Task<IClosePopupResult> TryClosePopupAsync(this INavigation navigation, CancellationToken token = default)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need interfaces for Popup results? We always return ClosePopupResult.

@TheCodeTraveler TheCodeTraveler added the needs discussion Discuss it on the next Monthly standup label Jun 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change This label is used for PRs that include a breaking change needs discussion Discuss it on the next Monthly standup pending documentation This feature requires documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants