Skip to content

feat: add reusable modal system with theme support and view registry#6

Merged
anilcancakir merged 3 commits into
mainfrom
feat/reusable-modal-system
Mar 28, 2026
Merged

feat: add reusable modal system with theme support and view registry#6
anilcancakir merged 3 commits into
mainfrom
feat/reusable-modal-system

Conversation

@anilcancakir

Copy link
Copy Markdown
Contributor

Summary

  • Add MagicStarterModalTheme — 13 Wind UI className token fields for customizable dialog styling via MagicStarter.useModalTheme()
  • Add MagicStarterConfirmDialog with ConfirmDialogVariant enum (primary/danger/warning) and internal MagicStarterDialogShell composition widget
  • Extend ViewRegistry with registerModal()/hasModal()/makeModal() + 3 auto-registered default modals
  • Refactor PasswordConfirmDialog and TwoFactorModal to read theme tokens at build time (no breaking changes)
  • Replace Material AlertDialog in team settings with MagicStarterConfirmDialog
  • 555 tests passing, 23 files changed (+1711, -76)

Test plan

  • 555 tests pass (flutter test --coverage)
  • flutter analyze --no-fatal-infos — clean (1 pre-existing info)
  • dart format --set-exit-if-changed . — 0 changes
  • New widget tests: DialogShell (7), ConfirmDialog (11), theme integration (3), registry modals (7), facade modals (10), team settings view (3)
  • Existing modal tests unbroken — backward compatible
  • Code review agent: APPROVED
  • Verifier agent: APPROVED
  • Linter agent: CLEAN

Add MagicStarterModalTheme (13 className tokens), MagicStarterDialogShell
(internal composition widget), MagicStarterConfirmDialog with ConfirmDialogVariant
enum (primary/danger/warning), and modal view registry (registerModal/hasModal/
makeModal with 3 auto-registered defaults). Refactor PasswordConfirmDialog and
TwoFactorModal to read theme tokens at build time. Replace Material AlertDialog
in team settings with ConfirmDialog. 555 tests passing.
Copilot AI review requested due to automatic review settings March 28, 2026 23:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds a reusable modal/dialog system to magic_starter with centralized theme tokens and a modal registry, then migrates existing dialogs and team settings confirms onto the new primitives.

Changes:

  • Introduces MagicStarterModalTheme + MagicStarter.useModalTheme() to control dialog styling via Wind UI className tokens.
  • Adds MagicStarterDialogShell (internal) and MagicStarterConfirmDialog (exported) with ConfirmDialogVariant.
  • Extends MagicStarterViewRegistry to register/build modals and auto-registers default modal keys; refactors existing dialogs and replaces team settings AlertDialog.

Reviewed changes

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

Show a summary per file
File Description
lib/src/magic_starter_manager.dart Adds modal theme storage/reset + default modal registrations.
lib/src/facades/magic_starter.dart Exposes useModalTheme() + modalTheme getter.
lib/src/ui/magic_starter_view_registry.dart Adds modal builder map + registerModal/hasModal/makeModal.
lib/src/ui/widgets/magic_starter_dialog_shell.dart New internal dialog shell composing Wind UI tokens.
lib/src/ui/widgets/magic_starter_confirm_dialog.dart New reusable confirm dialog built on the shell + variants.
lib/src/ui/widgets/magic_starter_password_confirm_dialog.dart Refactors styling to consume modalTheme tokens.
lib/src/ui/widgets/magic_starter_two_factor_modal.dart Refactors styling/maxWidth to consume modalTheme tokens.
lib/src/ui/views/teams/magic_starter_team_settings_view.dart Replaces Material AlertDialog confirms with MagicStarterConfirmDialog.
lib/magic_starter.dart Exports MagicStarterConfirmDialog from the barrel.
test/facades/magic_starter_facade_test.dart Adds coverage for modal theme defaults/override/reset + default modal keys.
test/ui/magic_starter_view_registry_test.dart Adds tests for modal registry operations and clear behavior.
test/ui/widgets/magic_starter_dialog_shell_test.dart New widget tests for shell rendering + theme token reads.
test/ui/widgets/magic_starter_confirm_dialog_test.dart New widget tests for confirm dialog behavior/variants/show().
test/ui/widgets/magic_starter_password_confirm_dialog_test.dart Adds modal-theme integration assertions.
test/ui/widgets/magic_starter_two_factor_modal_test.dart Adds modal-theme integration assertion.
test/ui/views/teams/magic_starter_team_settings_view_test.dart New widget tests asserting confirm dialog usage (no AlertDialog).
doc/basics/views-and-layouts.md Documents MagicStarterConfirmDialog usage and parameters.
doc/architecture/view-registry.md Documents modal registry API + default modal keys.
doc/architecture/manager.md Documents modal theme API and configuration.
README.md Updates theming docs (navigation + modal theme) and widget list.
CHANGELOG.md Records new modal theme/dialog/registry features.
CLAUDE.md Adds “gotchas” around modal theme ordering and className sourcing.
.claude/rules/widgets.md Adds dialog/variant/theme consumption rules for widgets.
Comments suppressed due to low confidence (2)

doc/architecture/view-registry.md:44

  • Docs: _modals is shown as Map<String, MagicStarterViewBuilder>, but the implementation uses a dedicated MagicStarterModalBuilder typedef. Update the snippet and add the typedef MagicStarterModalBuilder = Widget Function(); so the docs match the code.
The registry maintains three internal maps — one for view builders, one for layout builders, and one for modal builders:

```dart
final Map<String, MagicStarterViewBuilder> _builders = {};
final Map<String, MagicStarterLayoutBuilder> _layouts = {};
final Map<String, MagicStarterViewBuilder> _modals = {};

The builder typedefs:

typedef MagicStarterViewBuilder = Widget Function();
typedef MagicStarterLayoutBuilder = Widget Function(Widget child);
**doc/architecture/view-registry.md:101**
* Docs: The section says "Both methods throw StateError" but there are now three builders (`make`, `makeLayout`, `makeModal`). Update this wording to reflect that all the `make*` methods throw `StateError` when a key is missing.

Building Widgets

Widget make(String key)
Widget makeLayout(String key, {required Widget child})
Widget makeModal(String key)

Both methods throw StateError when the requested key is not registered:

throw StateError('No view builder registered for key "$key".');

[!NOTE]
A StateError from make() or makeLayout() usually means a feature flag is disabled. Feature-gated views (teams, two-factor, notifications) are only registered when their corresponding MagicStarterConfig.has*Features() flag returns true.

</details>



---

💡 <a href="/fluttersdk/magic_starter/new/main?filename=.github/instructions/*.instructions.md" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Add Copilot custom instructions</a> for smarter, more guided reviews. <a href="https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Learn how to get started</a>.

Comment thread lib/src/ui/widgets/magic_starter_confirm_dialog.dart Outdated
Comment thread lib/src/magic_starter_manager.dart Outdated
Comment thread doc/architecture/view-registry.md
Comment thread doc/architecture/manager.md
…itle

- Add try/catch to ConfirmDialog._onConfirm() to prevent stuck loading state
- Use trans('common.confirm') as default modal.confirm title instead of empty string
- Fix view-registry.md: MagicStarterModalBuilder typedef, "All three methods"
- Fix manager.md: maxWidth default is 448.0, not null
@anilcancakir anilcancakir merged commit 7296603 into main Mar 28, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants