Skip to content

Refactor/migrate material cupertino UI - #862

Merged
hm21 merged 6 commits into
hm21:stablefrom
goxxxa:refactor/migrate-material-cupertino-ui
Sep 8, 2026
Merged

hm21 merged 6 commits into
hm21:stablefrom
goxxxa:refactor/migrate-material-cupertino-ui

Conversation

@goxxxa

@goxxxa goxxxa commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR migrates the package from Flutter’s built-in Material and Cupertino libraries to the standalone [material_ui](https://pub.dev/packages/material_ui) and [cupertino_ui](https://pub.dev/packages/cupertino_ui) packages.

Flutter 3.47 decouples these design libraries from the Flutter SDK. Moving now keeps the package compatible with Flutter’s supported migration path and allows Material/Cupertino updates to be delivered independently of Flutter SDK releases.

Migration commands

dart fix --apply --code=migrate_design_widgets

Changes

  • Added material_ui and cupertino_ui as dependencies.
  • Replaced imports of package:flutter/material.dart and package:flutter/cupertino.dart.
  • Updated affected tests for Flutter 3.47 compatibility:
    • removed invalid const expressions;
    • configured Mockito to exclude createState, whose private return type cannot be mocked.

Validation

fvm flutter analyze
fvm flutter test

Breaking change

Consumers must migrate their own Material and Cupertino imports to the standalone packages when upgrading to this version.

Description

Related Issue: Closes #

Type of Change

  • ✨ New feature (non-breaking change which adds functionality)
  • 🛠️ Bug fix (non-breaking change which fixes an issue)
  • ❌ Breaking change (fix or feature that would cause existing functionality to change)
  • 🧹 Code refactor
  • ✅ Build configuration change
  • 📝 Documentation
  • 🗑️ Chore

Георгий and others added 3 commits September 7, 2026 19:10
Fix `createState()` returning the private state class in `BarColorPicker`
and `LayerWidget`, which broke `flutter analyze` on the generated Mockito
mocks and triggered `library_private_types_in_public_api`. Returning
`State<T>` again also removes the need for the `unsupportedMembers`
workaround in the mock spec.

Regenerate the stale Mockito mocks so they reference `material_ui`, drop a
duplicate import, and repair the import-section comments that the migration
displaced.

Pin `material_ui` and `cupertino_ui` instead of `any`, and bump to 14.0.0
since consumers must migrate their own Material and Cupertino imports.
@hm21

hm21 commented Sep 8, 2026

Copy link
Copy Markdown
Owner

Thanks a lot for this PR! 🙏 The migration itself is complete and clean — I verified that no package:flutter/material.dart or package:flutter/cupertino.dart import is left anywhere in lib/, example/lib/ or test/.

I pushed one follow-up commit onto your branch to get CI green and to prepare the release:

Analyzer error (the actual CI failure)

dart fix had rewritten createState() to return the private state class:

_BarColorPickerState createState() => _BarColorPickerState();

That is what broke the build. It triggered library_private_types_in_public_api in BarColorPicker and LayerWidget, and it made the generated Mockito mock invalid, because MockBarColorPicker.createState returns State<StatefulWidget> and cannot override a private return type.

Restoring State<BarColorPicker> / State<LayerWidget> fixes the root cause, so the unsupportedMembers: {#createState} workaround in the mock spec was no longer needed and has been reverted.

Stale generated mocks

bar_color_picker_test.mocks.dart and auto_image_test.mocks.dart were not regenerated — the latter was still on Mockito 5.4.4 and still importing package:flutter/material.dart. Both are now regenerated against material_ui.

Version constraints

material_ui: any / cupertino_ui: any are now pinned to ^1.1.1 / ^1.0.2 (in both pubspec.yaml and example/pubspec.yaml), and moved into the sorted dependency list. Unbounded constraints let a future major release land silently and are penalized by the pub.dev scoring.

Version bump + changelog

This is a genuine breaking change, not just an internal refactor. On the current stable channel (3.44, which CI pins) package:flutter/material.dart is still the SDK implementation and is not a re-export of material_ui, so the types are distinct:

error • A value of type 'ThemeData' (flutter/lib/src/material/theme_data.dart)
        can't be assigned to a variable of type 'ThemeData' (material_ui/lib/src/theme_data.dart)

Since ProImageEditorConfigs.theme is a ThemeData?, every app passing a theme has to migrate its own imports as well. I bumped the version to 14.0.0 and documented it in the changelog with the dart fix --apply --code=migrate_design_widgets migration hint.

Minor cleanups

Removed a duplicate package:mockito/annotations.dart import and repaired the import-section comments that the migration had displaced in four files.

Result: dart format, flutter analyze and all 551 tests pass locally on Flutter 3.44.0. Thanks again for taking care of this migration ahead of time — nicely done! 👍

Resolve the version and changelog conflicts in favour of 14.0.0 and keep
the 13.6.0 paint-editor entries as their own section, and migrate the
`package:flutter/material.dart` import that arrived with hm21#863.
@hm21

hm21 commented Sep 8, 2026

Copy link
Copy Markdown
Owner

Follow-up: #863 landed on stable in the meantime, which put this PR into a conflicting state. I merged stable into the branch and resolved it:

  • pubspec.yaml / CHANGELOG.md — kept 14.0.0 as the top section and preserved the new 13.6.0 paint-editor entries as their own section below it, so the release grouping stays intact.
  • draw_paint_item_opacity_test.dart — the new test from #863 still imported package:flutter/material.dart; migrated to material_ui.

The PR is MERGEABLE again and CI is green (dart format, flutter analyze, 571 tests). Ready for you whenever you want to merge it.

@hm21
hm21 force-pushed the refactor/migrate-material-cupertino-ui branch from 25a8f94 to aa7098e Compare September 8, 2026 08:37
hm21 added 2 commits September 8, 2026 11:23
CI pinned Flutter 3.44.0 only, so it never exercised the version this
migration is for. Run analyze and test as a matrix over both ends of the
supported range: 3.44.0, the minimum declared in `environment`, and 3.47,
where Material and Cupertino ship as separate packages.

Move the format check into its own job so it cannot silently skip when the
matrix changes, and build GitHub Pages with 3.47 as well.

Bump `actions/checkout` to v5, which runs on Node 24 and drops the Node 20
deprecation warning.
`dart format` reads analysis_options.yaml, whose `include` points at a lint
set shipped in a package. Without `flutter pub get` that include fails to
resolve, the formatter silently falls back to its defaults and wants to
reformat 107 files.
@hm21

hm21 commented Sep 8, 2026

Copy link
Copy Markdown
Owner

One more round — the CI workflows themselves needed updating, which turned out to be the most important part of this PR.

CI never tested the version this migration is for. flutter_analysis.yml and gh_pages.yml were both pinned to 3.44.0, while current stable is already 3.47.2. So every green check so far only proved the migration works on the old Flutter.

.github/workflows/flutter_analysis.yml now runs analyze and test as a matrix over both ends of the supported range:

  • 3.44.0 — the minimum declared in environment in pubspec.yaml
  • 3.47.x — where Material and Cupertino ship as separate packages

Both are green, so the package is verified on the old and the new world at once. I also confirmed this locally: 571 tests, flutter analyze and dart format all pass on 3.44.0 and 3.47.2.

Other workflow changes

  • The format check moved into its own job. Putting it behind an if: inside the matrix would have let it silently skip whenever the matrix versions change.
  • gh_pages.yml builds with 3.47 now. I verified flutter build web --release for the example app succeeds on 3.47.2, so the Pages deploy will not break after merge.
  • actions/checkout v4 → v5 in all three workflows. v4 runs on Node 20, which GitHub deprecated — the warning was visible in this PR's own run logs.

One thing worth knowing: the first attempt at the format job failed, which was a useful find. I had dropped flutter pub get from it, assuming formatting is purely syntactic. It is not — dart format reads analysis_options.yaml, and its include: package:flutter_lints/flutter.yaml cannot resolve without the packages, so the formatter falls back to its defaults and wants to reformat 107 files. The step is back in, with a comment explaining why it has to stay.

Not included (happy to do separately if you want them):

  • Flutter 3.47's pub get auto-rewrites analysis_options.yaml to exclude platform directories, and bumps MACOSX_DEPLOYMENT_TARGET from 11.0 to 12.0 in the example's Xcode project. Both are unrelated to this migration, so I reverted them rather than smuggling them in here.
  • stale.yml still uses actions/stale@v5; current is v11.

All checks green: Check formatting, Analyze & test (Flutter 3.44.0), Analyze & test (Flutter 3.47.x).

@hm21
hm21 merged commit 29011fa into hm21:stable Sep 8, 2026
3 checks 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