feat: design-system component library + view rewrite#78
Merged
Conversation
Add MagicStarterTokens.defaultAliases: 17 semantic role tokens (surface, fg, primary, border, destructive, success, warning, ...) mapped to light + dark wind className pairs via the bg-/text-/border-color- prefix convention. Components resolve colors through these roles; the brand stays a configurable WindThemeData primary color (bg-primary-600 shade reference). This map is the stable contract design:sync will generate against.
Establish the design-system migration pattern + atomic-folder template:
lib/src/ui/components/card/{card.dart, card.recipe.dart, card.preview.dart,
index.dart}. Card variant logic moves to a theme-driven buildCardRecipe()
WindRecipe; output is byte-identical to the legacy _defaultClassName for
every variant x noPadding combo (asserted by an equivalence gate against a
legacyDefaultClassName baseline). MagicStarterCard becomes a thin alias
subclass; CardVariant + barrel path stay byte-stable.
…rorState, Navbar) + composites (NotificationDropdown, UserProfileDropdown, TeamSelector, SocialDivider) - Add MagicFormField (slot root/label/hint/error; destructive error tone) - Add PageHeader component (title/subtitle/leading/actions/titleSuffix/inlineActions; byte-identical to MagicStarterPageHeader) - Add EmptyState (slot root/iconWrap/title/description/action; semantic tokens) - Add ErrorState (slot root/iconWrap/title/description/action; destructive tone title) - Add Navbar (responsive brand/children/trailing; hidden sm:flex nav links) - Migrate NotificationDropdown composite (StreamBuilder unread badge preserved) - Migrate UserProfileDropdown composite (triggerBuilder/alignment/logout preserved) - Migrate TeamSelector composite (teamResolver callbacks preserved) - Migrate SocialDivider composite (authTheme tokens preserved) - Convert 4 widget files to thin aliases keeping MagicStarterXxx names stable - All components follow canonical 4-file atomic folder shape (recipe/component/preview/index) - 996 tests pass; flutter analyze zero errors/warnings
Add the form-input (Button, Input, Textarea, Checkbox, Switch, Radio), display (Badge, Typography, Skeleton), selection (Select, Combobox, SegmentedControl, Tabs, Accordion), and overlay (Dialog, ConfirmDialog, BottomSheet, Toast, Tooltip, DropdownMenu) component families as WindRecipe-driven atomic folders on the Step 8 template, building on the semantic token layer. Migrate the existing dialogs/timezone-select to the component system as thin aliases (public names + barrel paths stay stable). Export the new components from the package barrel; collision-prone names (Switch, Dialog, ...) are hidden from Material in tests that need both.
Rewrite the auth, profile, notifications, and teams views plus the app and guest layouts to compose the new Button/Card/Switch/PageHeader/ SocialDivider/etc. components instead of inline W-widgets. Views are now Wind-exclusive (material imports scoped to 'show Icons' + the few needed Material shells), so the unprefixed component names no longer collide. Behavior, registry keys, controller contracts, gate abilities, refreshNotifier, and notification polling are all preserved.
Ship a DESIGN.md template covering all 17 semantic roles, typography on
the 4px logical scale, rounded/spacing, and key component entries with
{{ placeholder }} tokens. Consumers copy it, fill in brand hex + font,
run design:lint to validate, then design:sync to generate the wind theme.
Add the missing design.md.stub CHANGELOG entry, a README Design-System Components section (MagicStarterTokens + the component families + the import-collision note), and doc/basics/components.md (per the doc/basics per-feature convention). Update the CLAUDE.md test count; apply dart format.
There was a problem hiding this comment.
Pull request overview
This PR introduces a design-system layer to Magic Starter by adding MagicStarterTokens (semantic alias tokens) and a new atomic component library, then rewrites existing views/layouts to compose those components while preserving behavior and registry keys. It also expands the widget test suite and updates docs/changelog to reflect the new public API surface and import collisions.
Changes:
- Added
MagicStarterTokens.defaultAliasesand exported it from the top-level barrel to standardize semantic token usage across UI. - Added a Wave-4 atomic component library (recipe-driven) and migrated legacy widgets to thin backward-compatible aliases.
- Rewrote auth/profile/teams/notifications views + layouts to use the new components; updated/added tests and documentation accordingly.
Reviewed changes
Copilot reviewed 188 out of 188 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Documents design-system components, token aliases, and import-collision guidance. |
| CHANGELOG.md | Records the new token layer, component library, and view rewrite (plus collision note). |
| CLAUDE.md | Updates test-count reference for the expanded suite. |
| assets/stubs/design.md.stub | Adds a DESIGN.md template stub to support design:lint/sync flows. |
| doc/basics/components.md | Adds/updates component library documentation. |
| lib/magic_starter.dart | Exports MagicStarterTokens and new component indexes from the public barrel. |
| lib/src/ui/theme/magic_starter_tokens.dart | Defines the 17-role semantic alias contract (defaultAliases). |
| lib/src/ui/widgets/magic_starter_card.dart | Migrates legacy widget to a thin alias over the new component Card. |
| lib/src/ui/widgets/magic_starter_page_header.dart | Migrates legacy widget to a thin alias over PageHeader. |
| lib/src/ui/widgets/magic_starter_social_divider.dart | Migrates legacy widget to a thin alias over SocialDivider. |
| lib/src/ui/widgets/magic_starter_dialog_shell.dart | Migrates legacy widget to a thin alias over the new Dialog component. |
| lib/src/ui/widgets/magic_starter_confirm_dialog.dart | Preserves legacy ConfirmDialog API while delegating to migrated component(s). |
| lib/src/ui/widgets/magic_starter_notification_dropdown.dart | Migrates legacy widget to a thin alias over NotificationDropdown. |
| lib/src/ui/widgets/magic_starter_user_profile_dropdown.dart | Migrates legacy widget to a thin alias over UserProfileDropdown. |
| lib/src/ui/widgets/magic_starter_team_selector.dart | Migrates legacy widget to a thin alias over TeamSelector. |
| lib/src/ui/widgets/magic_starter_timezone_select.dart | Updates timezone select styling to use semantic-token slot recipes. |
| lib/src/ui/layouts/magic_starter_app_layout.dart | Adjusts imports and view composition to align with Wind-only/component approach. |
| lib/src/ui/layouts/magic_starter_guest_layout.dart | Adjusts imports and view composition to align with Wind-only/component approach. |
| lib/src/ui/views/auth/magic_starter_login_view.dart | Rewrites login view to use design-system Button/SocialDivider and Wind-only imports. |
| lib/src/ui/views/auth/magic_starter_register_view.dart | Rewrites register view to use design-system Button/SocialDivider and Wind-only imports. |
| lib/src/ui/views/auth/magic_starter_forgot_password_view.dart | Rewrites forgot-password view to use design-system Button and Wind-only imports. |
| lib/src/ui/views/auth/magic_starter_reset_password_view.dart | Rewrites reset-password view to use design-system Button and icon constants. |
| lib/src/ui/views/auth/magic_starter_two_factor_challenge_view.dart | Rewrites 2FA challenge view to use design-system Button. |
| lib/src/ui/views/auth/magic_starter_otp_verify_view.dart | Rewrites OTP verify view to use design-system Button. |
| lib/src/ui/views/profile/magic_starter_profile_settings_view.dart | Rewrites profile settings sections to use design-system Switch behavior. |
| lib/src/ui/views/teams/magic_starter_team_create_view.dart | Rewrites team create view to use component Card + PageHeader. |
| lib/src/ui/views/teams/magic_starter_team_settings_view.dart | Rewrites team settings view to use component Card + PageHeader. |
| lib/src/ui/views/teams/magic_starter_team_invitation_accept_view.dart | Updates imports/composition for Wind-only/component approach. |
| lib/src/ui/views/notifications/magic_starter_notifications_list_view.dart | Updates imports/composition to align with new component-driven UI. |
| lib/src/ui/views/notifications/magic_starter_notification_preferences_view.dart | Rewrites preference toggles to use design-system Switch(disabled: ...). |
| lib/src/ui/components/accordion/accordion.dart | Adds Accordion component. |
| lib/src/ui/components/accordion/accordion.recipe.dart | Adds Accordion slot recipe. |
| lib/src/ui/components/accordion/accordion.preview.dart | Adds Accordion preview. |
| lib/src/ui/components/accordion/index.dart | Accordion folder-local barrel. |
| lib/src/ui/components/badge/badge.dart | Adds Badge component. |
| lib/src/ui/components/badge/badge.recipe.dart | Adds Badge recipe (tone variants). |
| lib/src/ui/components/badge/badge.preview.dart | Adds Badge preview. |
| lib/src/ui/components/badge/index.dart | Badge folder-local barrel. |
| lib/src/ui/components/bottom_sheet/bottom_sheet.dart | Adds BottomSheet component with modal-theme-driven chrome. |
| lib/src/ui/components/bottom_sheet/bottom_sheet.recipe.dart | Adds BottomSheet slot recipe helper. |
| lib/src/ui/components/bottom_sheet/bottom_sheet.preview.dart | Adds BottomSheet preview. |
| lib/src/ui/components/bottom_sheet/index.dart | BottomSheet folder-local barrel. |
| lib/src/ui/components/button/button.dart | Adds Button component. |
| lib/src/ui/components/button/button.recipe.dart | Adds Button recipe (intent/size variants). |
| lib/src/ui/components/button/button.preview.dart | Adds Button preview. |
| lib/src/ui/components/button/index.dart | Button folder-local barrel. |
| lib/src/ui/components/card/card.dart | Migrates Card into atomic component folder shape. |
| lib/src/ui/components/card/card.recipe.dart | Adds theme-driven Card recipe (byte-identical gate supported by tests). |
| lib/src/ui/components/card/card.preview.dart | Adds Card preview. |
| lib/src/ui/components/card/index.dart | Card folder-local barrel. |
| lib/src/ui/components/checkbox/checkbox.dart | Adds Checkbox component. |
| lib/src/ui/components/checkbox/checkbox.recipe.dart | Adds Checkbox recipe. |
| lib/src/ui/components/checkbox/checkbox.preview.dart | Adds Checkbox preview. |
| lib/src/ui/components/checkbox/index.dart | Checkbox folder-local barrel. |
| lib/src/ui/components/combobox/combobox.dart | Adds Combobox component. |
| lib/src/ui/components/combobox/combobox.recipe.dart | Adds Combobox slot recipe. |
| lib/src/ui/components/combobox/combobox.preview.dart | Adds Combobox preview. |
| lib/src/ui/components/combobox/index.dart | Combobox folder-local barrel. |
| lib/src/ui/components/confirm_dialog/confirm_dialog.dart | Adds ConfirmDialog component. |
| lib/src/ui/components/confirm_dialog/confirm_dialog.recipe.dart | Adds ConfirmDialog recipe helper(s). |
| lib/src/ui/components/confirm_dialog/confirm_dialog.preview.dart | Adds ConfirmDialog preview. |
| lib/src/ui/components/confirm_dialog/index.dart | ConfirmDialog folder-local barrel. |
| lib/src/ui/components/dialog/dialog.dart | Adds Dialog component. |
| lib/src/ui/components/dialog/dialog.recipe.dart | Adds Dialog slot recipe helper(s). |
| lib/src/ui/components/dialog/dialog.preview.dart | Adds Dialog preview. |
| lib/src/ui/components/dialog/index.dart | Dialog folder-local barrel. |
| lib/src/ui/components/dropdown_menu/dropdown_menu.dart | Adds DropdownMenu component. |
| lib/src/ui/components/dropdown_menu/dropdown_menu.recipe.dart | Adds DropdownMenu className constants. |
| lib/src/ui/components/dropdown_menu/dropdown_menu.preview.dart | Adds DropdownMenu preview. |
| lib/src/ui/components/dropdown_menu/index.dart | DropdownMenu folder-local barrel. |
| lib/src/ui/components/empty_state/empty_state.dart | Adds EmptyState component. |
| lib/src/ui/components/empty_state/empty_state.recipe.dart | Adds EmptyState recipe helpers. |
| lib/src/ui/components/empty_state/empty_state.preview.dart | Adds EmptyState preview. |
| lib/src/ui/components/empty_state/index.dart | EmptyState folder-local barrel. |
| lib/src/ui/components/error_state/error_state.dart | Adds ErrorState component. |
| lib/src/ui/components/error_state/error_state.recipe.dart | Adds ErrorState recipe helpers. |
| lib/src/ui/components/error_state/error_state.preview.dart | Adds ErrorState preview. |
| lib/src/ui/components/error_state/index.dart | ErrorState folder-local barrel. |
| lib/src/ui/components/form_field/form_field.dart | Adds MagicFormField component. |
| lib/src/ui/components/form_field/form_field.recipe.dart | Adds MagicFormField className helpers. |
| lib/src/ui/components/form_field/form_field.preview.dart | Adds MagicFormField preview. |
| lib/src/ui/components/form_field/index.dart | MagicFormField folder-local barrel. |
| lib/src/ui/components/input/input.dart | Adds Input component. |
| lib/src/ui/components/input/input.recipe.dart | Adds Input recipe (state variants). |
| lib/src/ui/components/input/input.preview.dart | Adds Input preview. |
| lib/src/ui/components/input/index.dart | Input folder-local barrel. |
| lib/src/ui/components/navbar/navbar.dart | Adds Navbar component. |
| lib/src/ui/components/navbar/navbar.recipe.dart | Adds Navbar className helpers. |
| lib/src/ui/components/navbar/navbar.preview.dart | Adds Navbar preview. |
| lib/src/ui/components/navbar/index.dart | Navbar folder-local barrel. |
| lib/src/ui/components/notification_dropdown/notification_dropdown.dart | Adds NotificationDropdown component. |
| lib/src/ui/components/notification_dropdown/notification_dropdown.recipe.dart | Placeholder recipe file for canonical shape. |
| lib/src/ui/components/notification_dropdown/notification_dropdown.preview.dart | Adds NotificationDropdown preview. |
| lib/src/ui/components/notification_dropdown/index.dart | NotificationDropdown folder-local barrel. |
| lib/src/ui/components/page_header/page_header.dart | Adds PageHeader component (migrated from widget). |
| lib/src/ui/components/page_header/page_header.recipe.dart | Placeholder recipe file for canonical shape. |
| lib/src/ui/components/page_header/page_header.preview.dart | Adds PageHeader preview. |
| lib/src/ui/components/page_header/index.dart | PageHeader folder-local barrel. |
| lib/src/ui/components/radio/radio.dart | Adds Radio component. |
| lib/src/ui/components/radio/radio.recipe.dart | Adds Radio recipes (shell/indicator). |
| lib/src/ui/components/radio/radio.preview.dart | Adds Radio preview. |
| lib/src/ui/components/radio/index.dart | Radio folder-local barrel. |
| lib/src/ui/components/segmented_control/segmented_control.dart | Adds SegmentedControl component. |
| lib/src/ui/components/segmented_control/segmented_control.recipe.dart | Adds SegmentedControl slot recipe. |
| lib/src/ui/components/segmented_control/segmented_control.preview.dart | Adds SegmentedControl preview. |
| lib/src/ui/components/segmented_control/index.dart | SegmentedControl folder-local barrel. |
| lib/src/ui/components/select/select.dart | Adds Select component. |
| lib/src/ui/components/select/select.recipe.dart | Adds Select slot recipe. |
| lib/src/ui/components/select/select.preview.dart | Adds Select preview. |
| lib/src/ui/components/select/index.dart | Select folder-local barrel. |
| lib/src/ui/components/skeleton/skeleton.dart | Adds Skeleton component. |
| lib/src/ui/components/skeleton/skeleton.recipe.dart | Adds Skeleton recipe (shape variants). |
| lib/src/ui/components/skeleton/skeleton.preview.dart | Adds Skeleton preview. |
| lib/src/ui/components/skeleton/index.dart | Skeleton folder-local barrel. |
| lib/src/ui/components/social_divider/social_divider.dart | Adds SocialDivider component (migrated from widget). |
| lib/src/ui/components/social_divider/social_divider.recipe.dart | Placeholder recipe file for canonical shape. |
| lib/src/ui/components/social_divider/social_divider.preview.dart | Adds SocialDivider preview. |
| lib/src/ui/components/social_divider/index.dart | SocialDivider folder-local barrel. |
| lib/src/ui/components/switch/switch.dart | Adds Switch component. |
| lib/src/ui/components/switch/switch.recipe.dart | Adds Switch recipes (track/thumb). |
| lib/src/ui/components/switch/switch.preview.dart | Adds Switch preview. |
| lib/src/ui/components/switch/index.dart | Switch folder-local barrel. |
| lib/src/ui/components/tabs/tabs.dart | Adds Tabs component. |
| lib/src/ui/components/tabs/tabs.recipe.dart | Adds Tabs slot recipe. |
| lib/src/ui/components/tabs/tabs.preview.dart | Adds Tabs preview. |
| lib/src/ui/components/tabs/index.dart | Tabs folder-local barrel. |
| lib/src/ui/components/team_selector/team_selector.dart | Adds TeamSelector component. |
| lib/src/ui/components/team_selector/team_selector.recipe.dart | Placeholder recipe file for canonical shape. |
| lib/src/ui/components/team_selector/team_selector.preview.dart | Adds TeamSelector preview. |
| lib/src/ui/components/team_selector/index.dart | TeamSelector folder-local barrel. |
| lib/src/ui/components/textarea/textarea.dart | Adds Textarea component. |
| lib/src/ui/components/textarea/textarea.recipe.dart | Adds Textarea recipe (state variants). |
| lib/src/ui/components/textarea/textarea.preview.dart | Adds Textarea preview. |
| lib/src/ui/components/textarea/index.dart | Textarea folder-local barrel. |
| lib/src/ui/components/toast/toast.dart | Adds Toast component. |
| lib/src/ui/components/toast/toast.recipe.dart | Adds Toast recipe (variant axis). |
| lib/src/ui/components/toast/toast.preview.dart | Adds Toast preview. |
| lib/src/ui/components/toast/index.dart | Toast folder-local barrel. |
| lib/src/ui/components/tooltip/tooltip.dart | Adds Tooltip component. |
| lib/src/ui/components/tooltip/tooltip.recipe.dart | Adds Tooltip default className constant. |
| lib/src/ui/components/tooltip/tooltip.preview.dart | Adds Tooltip preview. |
| lib/src/ui/components/tooltip/index.dart | Tooltip folder-local barrel. |
| lib/src/ui/components/typography/typography.dart | Adds Typography component. |
| lib/src/ui/components/typography/typography.recipe.dart | Adds Typography recipe (variant axis). |
| lib/src/ui/components/typography/typography.preview.dart | Adds Typography preview. |
| lib/src/ui/components/typography/index.dart | Typography folder-local barrel. |
| lib/src/ui/components/user_profile_dropdown/user_profile_dropdown.dart | Adds UserProfileDropdown component. |
| lib/src/ui/components/user_profile_dropdown/user_profile_dropdown.recipe.dart | Placeholder recipe file for canonical shape. |
| lib/src/ui/components/user_profile_dropdown/user_profile_dropdown.preview.dart | Adds UserProfileDropdown preview. |
| lib/src/ui/components/user_profile_dropdown/index.dart | UserProfileDropdown folder-local barrel. |
| test/ui/widgets/magic_starter_card_test.dart | Adds/extends Card tests including byte-identical recipe equivalence gate. |
| test/ui/widgets/magic_starter_dialog_shell_test.dart | Updates tests for new Dialog export name collisions (hide Dialog). |
| test/ui/widgets/magic_starter_password_confirm_dialog_test.dart | Updates tests for new Dialog export name collisions (hide Dialog). |
| test/ui/widgets/magic_starter_two_factor_modal_test.dart | Updates tests for new Dialog export name collisions (hide Dialog). |
| test/ui/views/profile/magic_starter_profile_settings_newsletter_test.dart | Updates import to avoid Switch name collision. |
| test/ui/views/notifications/magic_starter_notification_preferences_view_test.dart | Updates for design-system Switch behavior (disabled vs onChanged == null). |
| test/ui/views/auth/magic_starter_login_view_social_test.dart | Updates divider assertions to new SocialDivider component name. |
| test/ui/views/auth/magic_starter_register_view_social_test.dart | Updates divider assertions to new SocialDivider component name. |
| test/ui/components/accordion/accordion_test.dart | Adds Accordion component tests. |
| test/ui/components/badge/badge_test.dart | Adds Badge component tests. |
| test/ui/components/bottom_sheet/bottom_sheet_test.dart | Adds BottomSheet component tests and export assertion. |
| test/ui/components/button/button_test.dart | Adds Button component tests. |
| test/ui/components/checkbox/checkbox_test.dart | Adds Checkbox component tests. |
| test/ui/components/combobox/combobox_test.dart | Adds Combobox component tests. |
| test/ui/components/confirm_dialog/confirm_dialog_test.dart | Adds ConfirmDialog component tests. |
| test/ui/components/dialog/dialog_test.dart | Adds Dialog component tests. |
| test/ui/components/dropdown_menu/dropdown_menu_test.dart | Adds DropdownMenu component tests. |
| test/ui/components/empty_state/empty_state_test.dart | Adds EmptyState component tests. |
| test/ui/components/error_state/error_state_test.dart | Adds ErrorState component tests. |
| test/ui/components/form_field/form_field_test.dart | Adds MagicFormField component tests. |
| test/ui/components/input/input_test.dart | Adds Input component tests. |
| test/ui/components/navbar/navbar_test.dart | Adds Navbar component tests and preview test. |
| test/ui/components/notification_dropdown/notification_dropdown_test.dart | Adds NotificationDropdown component tests. |
| test/ui/components/page_header/page_header_test.dart | Adds PageHeader component tests. |
| test/ui/components/radio/radio_test.dart | Adds Radio component tests. |
| test/ui/components/segmented_control/segmented_control_test.dart | Adds SegmentedControl component tests. |
| test/ui/components/select/select_test.dart | Adds Select component tests. |
| test/ui/components/skeleton/skeleton_test.dart | Adds Skeleton component tests. |
| test/ui/components/social_divider/social_divider_test.dart | Adds SocialDivider component tests. |
| test/ui/components/switch/switch_test.dart | Adds Switch component tests. |
| test/ui/components/tabs/tabs_test.dart | Adds Tabs component tests. |
| test/ui/components/team_selector/team_selector_test.dart | Adds TeamSelector component tests. |
| test/ui/components/textarea/textarea_test.dart | Adds Textarea component tests. |
| test/ui/components/toast/toast_test.dart | Adds Toast component tests. |
| test/ui/components/tooltip/tooltip_test.dart | Adds Tooltip component tests and barrel export assertion. |
| test/ui/components/typography/typography_test.dart | Adds Typography component tests. |
| test/ui/components/user_profile_dropdown/user_profile_dropdown_test.dart | Adds UserProfileDropdown component tests. |
| test/ui/views/auth/magic_starter_forgot_password_view_test.dart | Updates forgot-password view tests for component rewrite. |
| test/ui/views/auth/magic_starter_login_view_test.dart | Updates login view tests for component rewrite. |
| test/ui/views/auth/magic_starter_otp_verify_view_test.dart | Updates OTP verify view tests for component rewrite. |
| test/ui/views/auth/magic_starter_register_view_test.dart | Updates register view tests for component rewrite. |
| test/ui/views/auth/magic_starter_reset_password_view_test.dart | Updates reset-password view tests for component rewrite. |
| test/ui/views/auth/magic_starter_two_factor_challenge_view_test.dart | Updates 2FA challenge view tests for component rewrite. |
| test/ui/views/notifications/magic_starter_notifications_list_view_test.dart | Updates notifications list view tests for component rewrite. |
| test/ui/views/notifications/magic_starter_notification_preferences_view_test.dart | Updates preference matrix tests for Switch changes. |
| test/ui/views/profile/magic_starter_profile_settings_delete_account_test.dart | Updates profile settings tests for component rewrite. |
| test/ui/views/profile/magic_starter_profile_settings_email_verification_test.dart | Updates profile settings tests for component rewrite. |
| test/ui/views/profile/magic_starter_profile_settings_two_factor_test.dart | Updates profile settings tests for component rewrite. |
| test/ui/views/profile/magic_starter_profile_settings_view_test.dart | Updates profile settings view tests for component rewrite. |
| test/ui/views/teams/magic_starter_team_create_view_test.dart | Updates teams create view tests for component rewrite. |
| test/ui/views/teams/magic_starter_team_invitation_accept_view_test.dart | Updates invitation accept view tests for component rewrite. |
| test/ui/views/teams/magic_starter_team_settings_view_test.dart | Updates teams settings view tests for component rewrite. |
The switch track recipe now uses `flex items-center justify-start checked:justify-end` with `px-0.5` instead of `translate-x-*` (a no-op in Wind, so the thumb never moved). Pairs with the WSwitch fix that drops `relative` from the track so it stays a flex Row.
Dropped `justify-center` from the buttonRecipe base. In Wind that maps to WButton's Container alignment, which forces the button to fill its constraints (every default Button stacked one-per-row in a variant row). A default button now shrink-wraps its content (its `inline-flex` intent), verified 130px vs 800px. Form/modal buttons are unaffected: they pass a className override (the form theme ships `w-full`) that bypasses the recipe base.
Add package:magic_starter/previews.dart, a dev-only barrel that exposes every component preview (Button..UserProfileDropdown, TeamSelector, NotificationDropdown, dialogs, etc.) as (label, slug, builder) records via starterComponentPreviews(). Kept separate from the magic_starter.dart release barrel so the atomic-component 'previews stay out of release' rule holds; the records come from a function (no top-level const widget refs), so a consumer calling it behind a kReleaseMode/PREVIEW_ENABLED guard tree-shakes the whole set. Lets a consumer catalog surface the full component library without recreating previews.
doCreate only set the local currentTeamId after POST /teams; the backend current_team_id stayed on the previous team, so the resolver-driven sidebar name + active highlight showed the OLD team while local state and the member fetch pointed at the new one (REPORT #14, reproduced e2e: create opened the old team's settings). doCreate now PUTs /user/current-team with the new id before Auth.restore() (Jetstream create-then-switch); server, resolver, sidebar, and settings now agree. Verified end-to-end via dusk (telescope shows POST /teams -> PUT /user/current-team; sidebar + settings show the new team).
…kens, Wind-only previews) - Stop re-exporting *.preview.dart from 9 component index.dart barrels; the main barrel re-exports every index.dart, so this leaked dev-only previews into the release barrel. previews:refresh + the previews.dart dev barrel discover previews directly; preview tests now import the preview file directly. Fixes the form_field comment/export contradiction Copilot flagged and the same leak in 8 sibling components. - Tooltip: default panel + kTooltipDefaultPanelClassName use semantic alias tokens (bg-surface-container-high / text-fg / border-color-border) instead of hardcoded gray; corrected the doc comment to the real enableTriggerOnTap:true behavior (no PopoverController). - BottomSheet drag handle: semantic bg-surface-container-high, not bg-gray-*. - PageHeader/EmptyState/ErrorState previews render actions with the design-system Button + WText instead of Material ElevatedButton/Text. All 996 tests pass; analyze clean.
iOS inset-grouped settings primitives: grouped section (caption + rounded container + auto hairline dividers), list row (icon tile + title/subtitle + trailing slot + destructive tone, 44pt tap target), and drill nav row (value + chevron, MagicRoute.push). 4-file atomic contract + previews + tests.
Optional backLabel/backFallback render a leading chevron + parent-label control that calls MagicRoute.back(fallback:) (native pop -> history -> parent). Top-level pages omit it. Back-control className via pageHeaderTheme. Foundation for one consistent back affordance across authenticated pages.
GuestLayout used SingleChildScrollView(primary: true); with RouteTransition.none the outgoing+incoming guest routes briefly co-mount and two primary scroll views contend for the single PrimaryScrollController, detaching each other mid-layout (dropChild / wrong-build-scope cascade). primary: false fixes it.
Centered mobile-first sub-page wrapper composing the unified PageHeader (backLabel/backFallback pass-through) + a gap column for SettingsSections, SingleChildScrollView(primary: false). Export the 4 settings components from the package barrel (previews stay out, release boundary).
iOS-style Settings hub (grouped feature-gated nav rows, drill via push) and the Profile sub-page (photo, email-verification, identity form, destructive Delete). Add MagicStarterConfig route getters for the hub + sub-pages. Reuses the profile controller + delete-confirm dialog unchanged; registry wiring is a later step.
Three SettingsScaffold sub-pages reusing the 2FA wizard + password-confirm dialog + profile controller methods verbatim (no endpoint changes).
…zone, Newsletter) Appearance option-card theme selector (light/dark/system via WindTheme; persistence handled by the framework's existing theme_mode Vault wiring). Language/Timezone persist via doUpdateProfile; Newsletter toggle reused. Drop now-redundant deep imports in the settings row/nav-row tests.
Flat absolute routes for the hub + 8 sub-pages (feature-gated, RouteTransition.none) in the auth+layout.app group; register the 9 sub-page views as overridable registry defaults (drop the old profile.settings long-form registration, no alias); repoint the Settings nav destination to the /settings hub.
…pages Team create (drilled from team settings) and notification preferences (drilled from the settings hub) now pass backLabel/backFallback to the unified PageHeader; top-level landings (team settings, notifications list) keep no back. Consistent back behavior across authenticated starter pages.
Add SettingsSection/Row/NavRow/Scaffold records to starterComponentPreviews() so the dev-only /preview catalog surfaces them in light+dark.
Register the profile/newsletter controllers in the settings routes (MagicStatefulView resolves via Magic.find, which the registry-driven builders skipped -> 'Controller not found'). Redesign the back affordance to an icon-only chevron in the header leading slot (vertically centred with title+subtitle, no parent label) that navigates to the parent via MagicRoute.to; settings drill rows also go() instead of push(), eliminating the RouteTransition.none pop teardown assertion. Hub title uses 'Settings'.
Row title text-sm->text-base, subtitle text-xs->text-sm, icon tile size-9->size-10, min-h-11->min-h-12 + py-4 so rows read at iOS 17pt weight next to the sidebar nav. Scaffold column widens max-w-2xl -> lg:max-w-4xl so it is not a thin strip on desktop.
Scaffold paints bg-surface on a full-height wrapper around the scroll view (w-full h-full) so the page surface fills the whole content viewport instead of ending at the last section (the area below was showing the layout's grey content background). Remove the timezone + language fields from the Profile sub-page: they are their own dedicated Preferences sub-pages, so they are no longer duplicated. Tests updated to assert the de-duplication.
Scaffold column now fills the content area (w-full px-4 lg:px-8, generous max-w-7xl cap) instead of a narrow centred strip that left big desktop gutters. Form sub-pages (Profile, Password, Language, Timezone) now render the Save action BELOW the grouped card (outside the section) rather than inside it.
login -> register -> forgot navigations (RouteTransition.none, guest->guest) co-mount the outgoing and incoming pages and reparent the previous page's element tree, tearing it down mid-build (wrong build scope / dropChild). Wrap the guest page in KeyedSubtree(ValueKey(routePath)) so each route forces a clean unmount/mount, mirroring MagicStarterAppLayout. Auth screen navigation no longer blanks the page.
…ccount to Security User dropdown now lists Settings (-> hub) above Profile. Delete Account moved off the Profile form to a Danger section on the Security > Sessions sub-page (reuses the password-confirm dialog + doDeleteAccount unchanged).
The recipe root slot used inline-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. Use flex flex-row items-center so the control lays its segments out horizontally as intended.
…lumn, not flex-1) The title column grew (flex-1/Expanded) and pushed titleSuffix to the row's far edge. flex-initial (FlexFit.loose) shrinks for truncation but does not grow, so the suffix sits right after the title; the title row's own sm:flex-1 still right-aligns trailing actions.
…he screen bottom Shown on a shell content navigator, the modal overlay was confined to the content area and the sheet floated with a bottom gap on tall/wide screens. useRootNavigator: true spans the full viewport so the sheet + scrim anchor to the real screen bottom, flush, at every viewport size.
The install command's MagicApplication regex required title to be the sole argument; magic now scaffolds a titleSuffix too. Anchor on title: without the immediate closing paren, capture the trailing args, and re-emit them verbatim after the injected windTheme (comma only when there are no trailing args, so the multi-arg form does not produce a double comma).
… so caller className appends (WIND-1)
…-7b) BREAKING: Button->MSButton, Card->MSCard, EmptyState->MSEmptyState, etc. Removes the flat unprefixed component classes (no compat shim) so consumers no longer need 'hide' import combinators. See CHANGELOG migration table.
…ndent tests Adds MagicStarter.resetFallbackManagerForTests() (@VisibleForTesting) and calls it in the test util suite's setUp/tearDown, removing the test-ordering hazard on the process-wide fallback/warning statics. Documents the release-mode silent fallback and the ambient-WindTheme requirement for useWindTheme (post-review).
… h-full) The scaffold sits inside the app layout's vertical scroll (overflow-y-auto); a hard h-full there resolves to an unbounded height and the newer wind runtime asserts against it (h-full inside a vertical scroll). min-h-full fills the viewport as a floor while still growing with taller content. Surfaced by dusk QA of the Settings page in the uptizm consumer app.
…verflowed the test viewport) Matches the settings_section preview test pattern (SingleChildScrollView). Clears the last failing test so the suite is fully green.
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
MagicStarterTokenssemantic alias layer + the generic component library (~29 atomic-folder components, WindRecipe-driven), migrates the 13 existing widgets to thin aliases (names/barrel paths stable, className-equivalence-gated), and rewrites all views + layouts onto the components (behavior/registry-keys preserved). Adds design.md.stub + doc/basics/components.md. analyze 0, 996 tests.Cross-repo: this design-first component system spans 5 repos. Land in dependency order: wind (WindRecipe + 5 primitives) first, then magic (design:sync/lint, previews:refresh, make:component) and magic_devtools (preview catalog) which consume wind, then magic_starter (component library + view rewrite), then magic_example (consumer app). Branches are all
feat/design-first-component-system. Verified locally end-to-end (analyze 0, full suites green, real-browser e2e of the /preview catalog, release-strip confirmed).