magic_starter 0.0.1-alpha.15
magic_starter: ^0.0.1-alpha.15 copied to clipboard
Starter kit for Magic Framework. Auth, Profile, Teams, Notifications — 13 opt-in features with overridable views.
Changelog #
All notable changes to this project will be documented in this file.
[Unreleased] #
Changed #
-
Dependency constraints realigned to the 0.0.x release line.
magicis now^0.0.4(was a stale^1.0.0-alpha.13that no published magic satisfied) andmagic_notificationsis^0.0.1(was^0.0.1-alpha.1). The old^1.0.0-alpha.13constraint also conflicted withmagic_notifications'smagic ^0.0.3, so the graph only solved via the local path overrides; it now resolves cleanly against published packages. magic 0.0.4 pullsfluttersdk_wind ^1.2.0, which carries theWindRecipe/WindSlotRecipeAPI the component layer uses. -
BREAKING: every design-system component class is now
MS-prefixed (MS-7b): the flat, unprefixed component classes were renamed to anMS-prefixed namespace (Button->MSButton,Dialog->MSDialog, ...) and the old names were removed outright (no re-export, no@Deprecatedalias, no compat barrel). This ends thepackage:flutter/material.dartcollision that previously forced consumers to sprinklehideclauses (Switch,Dialog,Checkbox,Radio,Badge,Typography,BottomSheet,Tooltip,DropdownMenu,DropdownMenuItem,EmptyState,ErrorStateall shadowed Material or common consumer names). The already-MagicStarter*-prefixed public widgets (MagicStarterCard,MagicStarterPageHeader, ...), the per-axis enums (ButtonIntent,InputState,BadgeTone, ...), and the recipe functions/consts are unchanged. Migration: replace each old class name with itsMScounterpart and drop any now-unnecessaryhideclause.Old name New name Old name New name ButtonMSButtonTooltipMSTooltipInputMSInputDropdownMenuMSDropdownMenuTextareaMSTextareaDropdownMenuItemMSDropdownMenuItemCheckboxMSCheckboxMagicFormFieldMSFormFieldSwitchMSSwitchNavbarMSNavbarRadioMSRadioEmptyStateMSEmptyStateBadgeMSBadgeErrorStateMSErrorStateTypographyMSTypographySettingsSectionMSSettingsSectionSkeletonMSSkeletonSettingsRowMSSettingsRowSelectMSSelectSettingsNavRowMSSettingsNavRowComboboxMSComboboxSettingsScaffoldMSSettingsScaffoldSegmentedControlMSSegmentedControlCardMSCardTabsMSTabsPageHeaderMSPageHeaderAccordionMSAccordionSocialDividerMSSocialDividerAccordionItemMSAccordionItemNotificationDropdownMSNotificationDropdownDialogMSDialogUserProfileDropdownMSUserProfileDropdownBottomSheetMSBottomSheetTeamSelectorMSTeamSelectorToastMSToastConfirmDialogMSConfirmDialogNote:
MagicFormFieldbecomesMSFormField(theMagicsegment is dropped, not double-prefixed). TheMagicStarter*alias widgets keep their names and now subclass theMS-prefixed components (MagicStarterCard extends MSCard).
Fixed #
MagicStarter.managerno longer throws whenmagic_starteris unbound (MS-6): components that read theme through the facade (e.g.CardviaMagicStarter.cardTheme) threw"Service [magic_starter] is not registered"when rendered without a runningMagicStarterServiceProvider— e.g. a standalone widget test or a/previewcatalog entry.MagicStarter.managernow checksMagic.bound('magic_starter')first and, when unbound, falls back to a shared default-constructedMagicStarterManager()(its 7 sub-themes already hold const defaults) instead of throwing. The fallback emits a one-timekDebugModewarning ("MagicStarterManager not bound; using defaults...") so a genuine forgot-to-bind bug in a real app still surfaces in development; a bound manager still wins. Note: inkReleaseModethe fallback is silent (no warning) and renders unbranded defaults, so wireMagicStarterServiceProviderin production even though a missing binding no longer crashes.- Caller
classNamenow APPENDS onto the component recipe instead of replacing it (WIND-1): 14 components (Button,Badge,Input,Textarea,Card,Switch,Checkbox,Radio,Skeleton,Toast,Typography,DropdownMenu,Tooltip,SettingsSection) previously bypassed their recipe entirely when a caller passedclassName(if (className != null) return className!/className ?? recipe()), soButton(intent: primary, className: 'w-full')dropped the primary fill and every base token. Each component now routes the callerclassNamethrough the recipe's caller-slot (recipe(variants: {...}, className: className)), so it appends last and Wind's parse-time per-family last-wins resolves conflicts while every non-overridden base class survives.DropdownMenualso threads its per-itemclassName(active + disabled) through per-item recipes,RadioappendsindicatorClassName,SwitchappendsthumbClassName, andSettingsSectionappends bothcontainerClassNameandcaptionClassName.TooltipandDropdownMenu, which had hardcoded default strings and no recipe, now lift those defaults into smallWindRecipes (tooltipPanelRecipe,dropdownMenuPanelRecipe,dropdownMenuItemRecipe,dropdownMenuItemDisabledRecipe); the previouskTooltipDefaultPanelClassName/kDropdownMenu*ClassNamestring constants are removed in favor of these recipes. Default styling (no callerclassName) is byte-identical to before. SegmentedControlrendered its segments vertically: the reciperootslot usedinline-flex, which Wind does not support (no inline layout) and which falls back to a vertical flex column, so the segments stacked top-to-bottom instead of sitting side by side. Changedroottoflex flex-row items-centerso the control lays its segments out horizontally as intended.
Added #
MagicStarter.useWindTheme(WindThemeData)one-call theme adoption (MS-7a): a single call now derives all 7 magic_starter sub-themes (navigation, modal, form, card, page header, layout, auth) from aWindThemeData's semantic alias palette and delegates to the existinguseTheme(MagicStarterTheme)hook, so a consumer aligns every built-in surface to their brand without hand-building up to 7 sub-theme structs. Backed by a newMagicStarterTheme.fromWind(WindThemeData)factory that rebuilds each color-bearing className from the 17 semantic roles (bg-surface/bg-surface-container/bg-surface-container-high,text-fg/text-fg-muted/text-fg-disabled,bg-primary/text-on-primary/text-primary,border-color-border/border-color-border-subtle,bg-destructive/text-on-destructive/bg-destructive-container). Each alias carries its owndark:pair, so a single token replaces everybg-white dark:bg-gray-800-style pair. A role is emitted as a token only when the passed theme defines it (as an alias key or a backing color key); otherwise the property keeps the shipped default palette pair, so a partially-configured theme never renders a silent no-op surface. Purely additive:useThemeand every individualuse*Theme()setter still work and override afterward. Pair it withMagicStarterTokens.defaultAliases(or adesign:sync-generated alias map) to re-skin every surface. Seedoc/guides/wind-theme-adoption.mdfor the full alias-to-property mapping.setUpMagicStarterForTests()test utility (MS-6):lib/src/testing/magic_starter_test_utils.dart(exported from the release barrel) wraps theMagic.singleton('magic_starter', () => MagicStarterManager())idiom repeated across 16+ test files. CallsetUpMagicStarterForTests()for a default manager, orsetUpMagicStarterForTests(manager: myManager)to bind a pre-configured one. Combined with theMagicStarter.managerdefensive fallback above, tests may now omit this call entirely for components that only need default theme values.- First-class
fullWidthprop onButton,Input,Textarea(MS-2): each component gains abool fullWidth = falseconstructor prop. Because Material widgets ignore cross-axis stretch inside aColumn(flutter/flutter#19399), settingfullWidth: truewraps the renderedWButton/WInputin aSizedBox(width: double.infinity)at the widget layer instead of relying on aclassNametoken; the recipe stays width-agnostic (inputRecipe/textareaRecipeno longer bake an unconditionalw-fullinto theirbase).fullWidthis orthogonal tosize(a layout concern, not the padding/font scale) and defaults tofalse(content-width). package:magic_starter/previews.dart(dev-only barrel): exposes all 30 component previews as(label, slug, builder)records viastarterComponentPreviews(), so a consumer's dev-only preview catalog can surface the full component set (Button, Badge, ..., UserProfileDropdown, TeamSelector, NotificationDropdown) without duplication. Kept SEPARATE from themagic_starter.dartrelease barrel (the atomic-component contract keeps*.preview.dartout of release); the records are returned from a function (not a top-level const holding widget refs), so a consumer that only calls it behind akReleaseMode/PREVIEW_ENABLEDguard tree-shakes the whole set from release.design.md.stub: aDESIGN.mdtemplate shipped atassets/stubs/design.md.stubcovering all 17 semantic roles (surface,fg,primary,border,destructive,success,warning, and their variants), typography on the 4px logical scale, rounded/spacing scales, and key component entries with{{ placeholder }}tokens. Consumers copy it into their project root, fill in brand hex values and fonts, then rundesign:lintto validate anddesign:syncto generate the Wind theme. Pairs withMagicStarterTokens.defaultAliasesas the stable key contract.- Wave 4 design-system component library: 23 new generic UI components are now part of the public barrel (
package:magic_starter/magic_starter.dart). Each component lives in the canonical atomic-component folder shape (<name>.dart,<name>.recipe.dart,<name>.preview.dart,index.dart) underlib/src/ui/components/.- Form controls:
Button(withButtonIntent,ButtonSize,buttonRecipe),Input(withInputState,inputRecipe),Textarea(withTextareaState,textareaRecipe),Checkbox,Switch,Radio,Select(withselectRecipe),Combobox(withcomboboxRecipe). - Feedback and display:
Badge(withBadgeTone),Typography(withTypographyVariant),Skeleton(withSkeletonShape),Toast(withToastVariant),Tooltip,EmptyState,ErrorState. - Layout and navigation:
Accordion(withAccordionItem,accordionRecipe),SegmentedControl(withSegmentedControlSize,segmentedControlRecipe),Tabs(withtabsRecipe),Navbar,Dropdownmenu (DropdownMenu,DropdownMenuItem). - Overlay:
Dialog,BottomSheet. - Composition:
MagicFormField(label, hint, error wrapper). - Previously migrated components (
Card,PageHeader,SocialDivider,NotificationDropdown,UserProfileDropdown,TeamSelector,ConfirmDialog) were already barrel-reachable through their existing alias exports and are unchanged. - Collision resolved by the
MSprefix (see the BREAKING entry below): these components were initially added under bare names (Switch,Dialog,Checkbox,Radio,Badge,Typography,BottomSheet,Tooltip,DropdownMenu,DropdownMenuItem) that collided withpackage:flutter/material.dart. They now carry anMSprefix (MSSwitch,MSDialog, ...), so importing both packages no longer needs ahideclause.
- Form controls:
Changed #
- Wave 5 view rewrite: the auth (login, register, forgot, reset, two-factor-challenge, otp-verify), profile, notifications (list + preferences matrix), and teams (create, settings, invitation-accept) views plus both layouts (
MagicStarterAppLayout,MagicStarterGuestLayout) now compose the new design-system components (Button,Card,Switch,PageHeader,SocialDivider, etc.) instead of inline W-widgets. Views are now Wind-exclusive: barepackage:flutter/material.dartimports were replaced withwidgets.dart+material show Icons(and the few genuinely-needed Material shells viashow), so the new component names no longer collide. Behavior, registry keys (auth.*,profile.*,notifications.*,teams.*,layout.app,layout.guest), controller contracts, gate abilities,refreshNotifier, and notification polling are all preserved; only the presentation layer changed. - Card migrated to the atomic-component folder +
WindRecipe: the card now lives atlib/src/ui/components/card/in the canonical 4-file shape (card.dart→class Card,card.recipe.dart,card.preview.dart,index.dart) and resolves its root className through a theme-drivenWindRecipeinstead of inline string interpolation. The recipe output is byte-identical to the previous_defaultClassNamefor everyCardVariantxnoPaddingcombination (gated by an explicit equivalence test).MagicStarterCardis retained as a thin re-export alias ofCard, andCardVariantplus the barrel export path (package:magic_starter/magic_starter.dart) are unchanged, so existing callers and the widget-test suite are untouched. This establishes the verbatim template for the Wave 4 component migration.
Added #
MagicStarterTokens.defaultAliases: semantic token alias map with 17 roles (surface,surface-container,surface-container-high,fg,fg-muted,fg-disabled,primary,on-primary,primary-container,accent,border,border-subtle,destructive,on-destructive,destructive-container,success,warning). Each role maps to a light+dark wind className pair ('bg-... dark:bg-...'/'text-... dark:text-...'). Pass asWindThemeData(aliases: MagicStarterTokens.defaultAliases)so components resolve against semantic roles rather than palette utilities directly. This map is the stable key contract thatdesign:sync(Steps 20-21) will later regenerate fromDESIGN.md.
Fixed #
- User dropdown adds a Settings (hub) entry + items work on web: the user-profile dropdown now lists
Settings(-> the iOS settings hub) aboveProfile. The dropdown items previously appeared dead on web (clicking did nothing and the popover closed; reopening closed immediately) because of aWPopoverfocus-loss auto-dismiss — fixed upstream influttersdk_wind(see its changelog). - Account deletion moved off the Profile form to Security: the destructive Delete Account row no longer sits on the Profile sub-page (it read as tacked-on); it now lives in a Danger section at the bottom of the Security > Browser Sessions sub-page, reusing the same password-confirm dialog and
doDeleteAccountunchanged. - Guest auth screens no longer crash during in-app transitions:
MagicStarterGuestLayoutwrapped its content inSingleChildScrollView(primary: true), which attaches to the ambientPrimaryScrollController. Auth routes useRouteTransition.none, so navigating between guest screens (login -> register -> forgot, etc.) briefly mounts the outgoing and incoming routes together; twoprimary: truescroll views then contended for the singlePrimaryScrollControllerand detached each other mid-layout, producing adropChild/ "RenderBox.size accessed beyond scope" / "wrong build scope" assertion cascade (and, on the worst cold-start case, a red error screen). The scroll view is nowprimary: falseso each guest page owns its own implicit controller and never contends for the shared one. - PR #78 review (release boundary + semantic tokens + Wind-only previews):
- Component
index.dartbarrels no longer re-export their*.preview.dart(9 components: error_state, empty_state, navbar, form_field, notification_dropdown, social_divider, page_header, user_profile_dropdown, team_selector). Previews are dev-only and must stay out of the release barrel (magic_starter.dartre-exports everyindex.dart);previews:refreshand thepreviews.dartdev barrel discover*.preview.dartdirectly, so the exports leaked previews into release for no benefit. Preview tests now import the preview file directly. Tooltipdefault panel +kTooltipDefaultPanelClassNameuse semantic alias tokens (bg-surface-container-high text-fg border border-color-border) instead of hardcoded gray palette utilities, so tooltips re-skin viaMagicStarterTokens/design:sync. TheTooltipdoc comment was corrected to describe the actualenableTriggerOnTap: truebehavior (it does not use aPopoverController).BottomSheetdrag handle usesbg-surface-container-highinstead ofbg-gray-300 dark:bg-gray-600.PageHeader/EmptyState/ErrorStatepreviews render their action with the design-systemButton+WTextinstead of MaterialElevatedButton/Text, keeping previews Wind-only and dropping the Material import churn.
- Component
- Creating a team now switches to it.
MagicStarterTeamController.doCreateonly set the localcurrentTeamIdnotifier afterPOST /teams; the backend'scurrent_team_idstayed on the previous team, so the resolver-driven sidebar name and active-team highlight showed the OLD team while local state and the member fetch pointed at the new one (REPORT #14, confirmed via e2e: create opened the old team's settings).doCreatenow callsPUT /user/current-teamwith the new id beforeAuth.restore()(Jetstream create-then-switch), so the server, resolver, sidebar, and settings all agree on the new team. Buttonno longer forces full-width: thebuttonRecipebase droppedjustify-center, which in Wind maps to WButton'sContaineralignment and made every defaultButton()expand to fill its constraints (stacking one-per-row in a variant row). A default button now shrinks to its content (itsinline-flexintent), with the label centered by the shrink-wrapped padding box. Form/modal buttons are unaffected: they pass aclassNameoverride (the form theme shipsw-full), which bypasses the recipe base entirely.- Create team opens the new team's settings:
MagicStarterTeamController.activeTeamNamenow matches the localcurrentTeamId(when set) against the resolver'sallTeams()by id, falling back to the resolver'scurrentTeam()when no match exists. PreviouslyactiveTeamIdpreferred the localcurrentTeamIdnotifier (set on create/switch) whileactiveTeamNameread only the resolver'scurrentTeam(), so after creating a team the settings view pre-filled the OLD team's name and effectively opened the old team (#14).
Removed #
- Breaking: Standalone CLI entrypoint — removed
bin/magic_starter.dartanddart run magic_starter:*commands. Commands now surface via the host app's artisan dispatcher. Migrate:dart run magic_starter:installbecomesdart run <app>:artisan starter:install(registerStarterArtisanProviderin your app'sartisan.providerslist). - Removed magic_cli dependency: CLI now builds on
fluttersdk_artisan ^0.0.8.
Changed #
- plugin:install auto-scaffolds starter:
install.yamlnow declaresbootstrap_command: starter:installsoplugin:install magic_starterautomatically runs the full starter scaffold (config, routes, middleware, dashboard) without a separate manual step. Requiresfluttersdk_artisan ^0.0.9which introduced auto-execution of thebootstrap_commandfield. Pass--no-bootstrapto skip the auto-run. - post_install message: reworded so it no longer flatly claims the
starter:installbootstrap succeeded (a chained-bootstrap failure previously left the message asserting a scaffold that never happened). It now tells the operator to rundart run <app>:artisan starter:installby hand if the bootstrap exited non-zero orlib/config/magic_starter.dartis missing, shows the--features=one-liner, and documents the--no-bootstrapopt-out. Pairs withfluttersdk_artisan's fix that surfaces a non-zero bootstrap exit code. - Install is manifest-driven — static scaffolding (config publish, provider injection) now driven by
install.yamlmanifest; dynamic logic (feature toggles, interactive mode) handled by fluent override inMagicStarterInstallCommand.
Added #
- Read-only MCP tool —
starter_doctordiagnostic command exposed as a read-only MCP tool viaStarterArtisanProvider.mcpTools().
🐛 Bug Fixes #
- Social login translation keys: the install-generated
assets/lang/en.json(fromassets/stubs/install/en.stub) now shipsauth.sign_in_withandauth.sign_up_with. The social-login buttons (SocialAuthButtonsfrommagic_social_auth) calltrans('auth.sign_in_with', {'provider': ...}), butmagic_social_authships no lang file and magic loads translations only from the consumer'sassets/lang, so a freshstarter:installwithsocial_loginenabled previously rendered raw keys ("auth.sign_in_with") instead of "Sign in with Google". Surfaced by a full reference-app E2E bring-up. - Mobile Header Brand:
MagicStarterAppLayoutmobile topbar now honorsnavigationTheme.brandBuilder, so custom brand widgets render consistently across breakpoints when provided (#65) - Page Header Title Truncation:
MagicStarterPageHeaderThemedefaults now useline-clamp-2instead oftruncatefortitleClassNameandsubtitleClassName, so long titles wrap to a second line on narrow viewports (e.g. iPhone-width screens) instead of clipping to "AI sett..." (#67)
🧪 Tests #
- wind 1.1.x widget-test compatibility: the two-factor modal and password confirm dialog widget tests drove input via
find.byType(TextField), which broke once CI resolvedfluttersdk_wind1.1.x (the Material-freeWInput/WFormInputrewrite renders anEditableTextinstead of a MaterialTextField). Both files now resolve the field viafind.descendant(of: find.byType(WFormInput), matching: find.byType(EditableText)), scoping the search to the single form input so the two-factor setup step's selectable secret-keyEditableTextis not matched by accident.
0.0.1-alpha.14 - 2026-04-16 #
✨ New Features #
- Unified Theme System: Added
MagicStarterThemewith 7 sub-themes (form,card,navigation,modal,layout,pageHeader,auth) set all theme tokens in one call viaMagicStarter.useTheme() - Builder Slots: Added
MagicStarter.view.slot()for partial view customization — override specific sections (header, footer, sidebar) without replacing the entire view - Granular Publish Command:
dart run magic_starter:publish --tag=views:auth.loginpublishes a single view file to the host app for full ownership - Auto-wire Published Views: Published views are automatically wired into
AppServiceProviderso they take effect immediately without manual registration - Doctor: Published View Detection:
dart run magic_starter:doctornow detects published views and reports wiring status — flags views that are published but not registered - Layout Theme Drawer Shade: Added
drawerBackgroundLightShadetoMagicStarterLayoutThemefor consistent drawer background customization
🐛 Bug Fixes #
- CLI: Cross-platform paths: Replaced POSIX string manipulation with
package:pathin publish and doctor commands for Windows compatibility - CLI: boot() injection: Publish auto-wire now locates the
boot()method by signature and brace-depth tracking instead of fragile second-to-last}heuristic - Team Settings: Invite button now reads className from
MagicStarter.modalTheme.primaryButtonClassNameinstead of hardcoded Wind UI tokens
🧪 Tests #
- Added slot injection widget tests for 7 views:
forgot_password,reset_password,two_factor_challenge,otp_verify,teams.create,teams.invitation_accept,notifications.preferences - Added
drawerBackgroundLightShadedefault value test to theme test suite
📚 Documentation #
- Manager: Added unified theme section, 5 new sub-theme sections (form, auth, card, page header, layout), updated facade methods table with all theme accessors
- View Registry: Added Builder Slots section documenting slot/hasSlot/buildSlot API
- CLAUDE.md: Added publish/uninstall commands, updated manager description, added customization gotchas, updated test count
0.0.1-alpha.13 - 2026-04-09 #
🐛 Bug Fixes #
- Icon Tree-Shaking: Extracted all runtime-conditional
Icons.*references intostatic constfields for Flutter web tree-shaking compatibility — fixes 11+ broken icon usages across 10 files (#37)
0.0.1-alpha.12 - 2026-04-09 #
✨ New Features #
- Sidebar Footer: Added
sidebarFooterBuilderslot viaMagicStarter.useSidebarFooter()— renders custom widget between navigation and user menu in both desktop sidebar and mobile drawer (#27) - MagicStarterUserProfileDropdown: Moved theme toggle from sidebar bottom bar into user profile dropdown menu — sidebar now shows only avatar, name, and notification bell (#30)
🐛 Bug Fixes #
- MagicStarterUserProfileDropdown: Fixed menu overflow when many profile menu items are registered — wrapped menu items in scrollable
overflow-y-autoWDiv, keeping header and logout footer fixed (#28) - Sidebar Navigation: Fixed overflow when many nav items exceed viewport height — added
overflow-y-autoto navigation WDiv so items scroll while brand, team selector, and user menu remain fixed (#29)
📚 Documentation #
- Manager: Added
useSidebarFooter()section and facade entry to manager doc - Views & Layouts: Updated theme toggle location from sidebar to user profile dropdown
- README: Added layout customization section with
useHeader()anduseSidebarFooter()examples
0.0.1-alpha.11 - 2026-04-07 #
✨ New Features #
- MagicStarterPageHeader: Added
titleSuffix(Widget?) for inline widgets after title (e.g. status badges) andinlineActions(bool) to force single-row layout on all screen sizes (#24)
📚 Documentation #
- Release Command: Added critical tag format warning —
publish.ymlrequires tags withoutvprefix (#23)
0.0.1-alpha.10 - 2026-04-07 #
🐛 Bug Fixes #
- MagicStarterDialogShell: Fixed bottom overflow when body content exceeds viewport — removed
flex flex-colfrom outer WDiv that broke constraint propagation to inner Column; body now scrolls correctly with sticky header/footer (#21)
🔧 Improvements #
- Dependencies: Bumped minimum
magicto^1.0.0-alpha.7— updated all test setUp blocks to bindAuthManagerin the IoC container, matching the new container-resolvedAuthfacade
0.0.1-alpha.9 - 2026-04-04 #
✨ New Features #
- MagicStarterHideBottomNav: New
InheritedWidgetthat signalsMagicStarterAppLayoutto hide the mobile bottom navigation bar for fullscreen routes — wired into layout and exported from barrel (#19)
📚 Documentation #
- State/Controller Registration Guide: New architecture reference (
doc/architecture/controllers.md) covering the lazy singleton pattern,MagicController + MagicStateMixinusage, controller lifecycle, view binding, and a decision tree for eager vs lazy vs per-view registration (#18) - State Management Getting-Started Guide: New practical guide (
doc/guides/state-management.md) with end-to-end examples — state class, view integration, and testing patterns for consumer apps (#18) - Scaffolded Stub:
app_service_provider.stubnow includes state registration guidance comments showing the recommendedMagic.findOrPut()pattern (#18) - Cross-References:
doc/architecture/service-provider.mdnow links to the new controllers doc (#18)
🔧 Improvements #
- CI: Bumped
codecov/codecov-actionfrom v5 to v6 (#16)
0.0.1-alpha.8 - 2026-03-31 #
🐛 Bug Fixes #
- MagicStarterDialogShell: Fixed mobile overflow —
maxHeightnow computed from safe area (MediaQuery.viewPaddingOf) instead of raw screen height; added verticalinsetPadding(24px) to prevent dialog from extending to screen edges (#13) - MagicStarterPasswordConfirmDialog: Same safe area fix — replaced hardcoded
maxHeight: 600withsafeHeight * 0.85; added verticalinsetPadding - MagicStarterTwoFactorModal: Same safe area fix — replaced hardcoded
maxHeight: 800withsafeHeight * 0.85; added verticalinsetPadding
0.0.1-alpha.7 - 2026-03-29 #
✨ New Features #
- MagicStarterPasswordConfirmDialog: Added
ConfirmDialogVariantsupport (primary,danger,warning) — confirm button now resolves color from variant via_resolveConfirmClassName(), matchingMagicStarterConfirmDialogbehavior. Both constructor andshow()accept optionalvariantparameter, defaults toConfirmDialogVariant.primaryfor backwards compatibility.
🔧 Improvements #
- Profile Settings: Standardized dialog variants across all password-confirm call sites —
dangerfor session revocation,warningfor 2FA disable and recovery code regeneration,primaryfor neutral confirmations (enable 2FA, view codes)
0.0.1-alpha.6 - 2026-03-29 #
🐛 Bug Fixes #
- MagicStarterPasswordConfirmDialog: Footer buttons now right-aligned — added
w-fullto footer WDiv sojustify-endstretches to container width - MagicStarterTwoFactorModal: Footer buttons now right-aligned in both setup and recovery steps — same
w-fullfix applied to both footer locations
🔧 Improvements #
- MagicStarterTwoFactorModal: Extracted duplicated footer className to shared
_footerClassNameconst — reduces divergence risk
0.0.1-alpha.5 - 2026-03-29 #
Changed #
- MagicStarterDialogShell: Now exported publicly from the barrel (
package:magic_starter/magic_starter.dart) — consumer apps can compose custom dialogs on top of it - MagicStarterDialogShell:
footerparameter replaced withfooterBuilder(Widget Function(BuildContext dialogContext)?) — provides the dialog's ownBuildContextso callers can callNavigator.pop(dialogContext)without needing an outer context
Fixed #
- MagicStarterConfirmDialog and MagicStarterPasswordConfirmDialog: Buttons are now compact and right-aligned (
justify-end gap-2 wrap) — previously rendered as full-width (flex-1) buttons that stretched across the footer - MagicStarterDialogShell: Body no longer creates a gap between scrollable content and the footer when content is shorter than the available height — switched from
SingleChildScrollViewtoListView(shrinkWrap: true)
0.0.1-alpha.4 - 2026-03-29 #
✨ New Features #
- MagicStarterModalTheme: Added configurable modal theme system via
MagicStarter.useModalTheme()with 13 Wind UI className token fields (containerClassName, headerClassName, bodyClassName, footerClassName, titleClassName, descriptionClassName, primaryButtonClassName, secondaryButtonClassName, dangerButtonClassName, warningButtonClassName, errorClassName, inputClassName, maxWidth). All fields optional — zero breaking changes. - MagicStarterConfirmDialog: Generic confirmation dialog with
ConfirmDialogVariantenum (primary,danger,warning). Staticshow()factory supports asynconConfirmcallback, custom labels, and description. Exported from barrel. - Modal View Registry: Extended
MagicStarterViewRegistrywithregisterModal(key, builder),hasModal(key), andmakeModal(key). Three default modals auto-registered:modal.confirm,modal.password_confirm,modal.two_factor. - MagicStarterDialogShell: Internal composition widget with sticky header/footer and scrollable body. Uses Material Dialog shell + Wind UI content. Not exported — internal use only.
🔧 Improvements #
- PasswordConfirmDialog: Now reads theme tokens from
MagicStarter.manager.modalThemeinstead of hardcoded classNames - TwoFactorModal: Now reads theme tokens from
MagicStarter.manager.modalThemeinstead of hardcoded classNames - Team Settings: Replaced Material
AlertDialogwithMagicStarterConfirmDialog.show()usingConfirmDialogVariant.danger
0.0.1-alpha.3 - 2026-03-26 #
✨ New Features #
- MagicStarterCard: Added
CardVariantenum (surface,inset,elevated) and avariantparameter so consumer apps can choose the card's visual style. Default isCardVariant.surface, which reproduces the original flat-border appearance and is fully backward-compatible. - MagicStarterPageHeader: Existing
actions(List - Configurable navigation theme: Added
MagicStarterNavigationThemeclass andMagicStarter.useNavigationTheme()to allow consumer apps to override navigation colors and styles without breaking changes.activeItemClassName— sidebar/drawer active item tokens (default:active:text-primary active:bg-primary/10 dark:active:bg-primary/10)hoverItemClassName— sidebar/drawer hover tokens (default:hover:bg-gray-100 dark:hover:bg-gray-800)brandClassName— brand/logo text className including gradient support (default:text-lg font-bold text-primary)brandBuilder— custom brand widget builder (image/SVG/styled text); overridesbrandClassNamewhen setbottomNavActiveClassName— bottom nav active icon/label tokens (default:active:text-primary)avatarClassName— sidebar user menu avatar background (default:bg-primary/10 dark:bg-primary/10)avatarTextClassName— sidebar user menu avatar initial color (default:text-sm font-bold text-primary)dropdownAvatarClassName— profile dropdown trigger avatar background (default:bg-gradient-to-tr from-primary to-gray-200)- All fields optional — zero breaking changes, existing apps continue to work unchanged
0.0.1-alpha.2 - 2026-03-25 #
🐛 Bug Fixes #
- Install Command: Use version dependency (
^0.0.1-alpha.1) formagic_notificationsinstead of hardcoded relative path that only works in monorepo development environment
0.0.1-alpha.1 - 2026-03-25 #
✨ Core Features #
- Authentication: Login, register, forgot/reset password with email and phone identity modes
- Guest Auth: OTP-based phone login with send and verify flow
- Two-Factor Authentication: Enable/disable 2FA with QR code setup, OTP confirmation, and recovery codes
- Social Login: OAuth integration with configurable providers
- Profile Management: Photo upload, email/password change, email verification, session management, timezone selection
- Extended Profile: Additional profile fields with locale and timezone defaults
- Teams: Create teams, switch active team, invite members, manage roles
- Notifications: Real-time polling, mark read/unread, notification preference matrix
- Newsletter: Simple subscribe/unsubscribe controller
- 13 Feature Toggles: All opt-in — teams, profile_photos, registration, two_factor, sessions, guest_auth, phone_otp, newsletter, email_verification, extended_profile, social_login, notifications, timezones
- 9 Gate Abilities: Authorization checks for profile sections (photo, email, phone, password, verify-email, two-factor, newsletter, sessions, delete-account)
- View Registry: String-keyed view factory — host app can override any screen or layout
- Wind UI: Tailwind-like className system — no Material widgets in layouts
- CLI Tools: install, configure, doctor, publish, uninstall commands with stub templates
- 2 Layouts: AppLayout (authenticated) and GuestLayout (auth pages)
- 12 Views: 6 auth, 1 profile, 3 teams, 2 notifications
- 10 Widgets: Reusable Wind UI components (auth form card, card, password confirm dialog, team selector, notification dropdown, two-factor modal, timezone select, user profile dropdown, social divider, page header)
🐛 Bug Fixes #
- Timezone: Fix API field name and add comprehensive null safety checks
- Auth: Correct register endpoint from
/auth/loginto/auth/register - UI: Remove flex Row from password confirm dialog buttons to prevent overflow
🔧 Improvements #
- Auth Events: Add auth restored listener for app reload on team switch
- Validation: Add input validation and network error handling to auth controllers
- Config: Add HTTP timeout and retry configuration
- i18n: Add notification and network error translation keys to en.stub
📚 Documentation #
- README: Full pub.dev-ready README with badges, features table, quick start guide
- doc/ folder: Comprehensive documentation (installation, configuration, authentication, profile, teams, notifications, views, CLI, architecture)
- CLAUDE.md: Rewrite to match Magic ecosystem format
- Publishing: Package metadata, CI/CD workflows, issue templates, LICENSE