feat: add RoundedSuperellipseInputBorder#177220
Conversation
faec135 to
6d975e6
Compare
There was a problem hiding this comment.
Code Review
This pull request introduces RoundedSuperellipseInputBorder, a new InputBorder that uses a superellipse shape, which is a great addition for achieving iOS-style aesthetics in text fields. The changes include the new border class, corresponding unit tests, and a runnable example with its own test. The code is well-documented and follows the project's conventions.
My main feedback is regarding the implementation of _gapBorderPath, which is responsible for creating the gap for the floating label. The current implementation has some inefficiencies and may produce visual artifacts. I've left a detailed comment with suggestions for improvement.
Overall, this is a solid contribution that adds a useful new widget to the framework.
| Path _gapBorderPath( | ||
| Canvas canvas, | ||
| RSuperellipse center, | ||
| double outerWidth, | ||
| double start, | ||
| double extent, | ||
| ) { | ||
| // Similar to OutlineInputBorder, we need to draw a path with a gap for the floating label. | ||
| // For superellipses, we'll use a simplified approach that draws the border in sections. | ||
|
|
||
| final Path path = Path(); | ||
|
|
||
| // For simplicity, we'll draw three sections: left, right, and bottom. | ||
| // The top section will have the gap. | ||
|
|
||
| // Start from top-left, accounting for the gap | ||
| if (start > 0) { | ||
| // Draw partial top-left to gap start | ||
| final Path topLeftPath = Path(); | ||
| topLeftPath.addRSuperellipse(center); | ||
|
|
||
| // Create a clipping region for the left part of the top edge | ||
| final Rect clipRect = Rect.fromLTRB( | ||
| center.left, | ||
| center.top, | ||
| start, | ||
| center.top + center.height / 2, | ||
| ); | ||
|
|
||
| final Path clippedPath = Path.combine( | ||
| PathOperation.intersect, | ||
| topLeftPath, | ||
| Path()..addRect(clipRect), | ||
| ); | ||
| path.addPath(clippedPath, Offset.zero); | ||
| } | ||
|
|
||
| // Draw from gap end to top-right | ||
| if (start + extent < outerWidth) { | ||
| final Path topRightPath = Path(); | ||
| topRightPath.addRSuperellipse(center); | ||
|
|
||
| final Rect clipRect = Rect.fromLTRB( | ||
| start + extent, | ||
| center.top, | ||
| center.right, | ||
| center.top + center.height / 2, | ||
| ); | ||
|
|
||
| final Path clippedPath = Path.combine( | ||
| PathOperation.intersect, | ||
| topRightPath, | ||
| Path()..addRect(clipRect), | ||
| ); | ||
| path.addPath(clippedPath, Offset.zero); | ||
| } | ||
|
|
||
| // Draw bottom and sides (no gap) | ||
| final Path bottomPath = Path(); | ||
| bottomPath.addRSuperellipse(center); | ||
|
|
||
| final Rect clipRect = Rect.fromLTRB( | ||
| center.left, | ||
| center.top + center.height / 2, | ||
| center.right, | ||
| center.bottom, | ||
| ); | ||
|
|
||
| final Path clippedPath = Path.combine( | ||
| PathOperation.intersect, | ||
| bottomPath, |
There was a problem hiding this comment.
This method has a few issues that should be addressed:
- Unused Parameter: The
canvasparameter is not used and can be removed from the method signature and call site inpaint(). - Inefficiency: The same
RSuperellipsepath is created three times. It would be more efficient to create it once and reuse it. - Potential Visual Artifacts: The current approach of splitting the shape into a top half and a bottom half using clipping rectangles is likely to create a visible seam on the left and right sides of the border when it's stroked. A more robust solution would be to construct a single, continuous path for the gapped border, similar to how
OutlineInputBorder._gapBorderPathis implemented. This would avoid any seams.
Consider refactoring this method to address these points for better performance and rendering quality.
a93b00e to
cd9f937
Compare
|
Sorry, I thought I commented on this PR. Anyway, I was going to say that I'd like more discussion under #176987 before moving forward with actual coding. Can you take a look? |
Sure, I will take a look. |
|
@rkishan516 How do you think of my comment under #176987 ? If you plan to work on it, we can keep this PR open or turn it into a draft in case you need more time. If not, we might close this PR. Thanks for your contribution. |
Yes @dkwingsmt, I agree with your second preference: Create a generic ShapedInputBorder that accepts any ShapeBorder. I will push the change shortly. |
5f2b493 to
13a00d1
Compare
|
This pull request executed golden file tests, but it has not been updated in a while (20+ days). Test results from Gold expire after as many days, so this pull request will need to be updated with a fresh commit in order to get results from Gold. For more guidance, visit Writing a golden file test for Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
| } | ||
|
|
||
| @override | ||
| bool get preferPaintInterior => true; |
There was a problem hiding this comment.
Shouldn't it be shape.preferPaintInterior, since the provided shape might not have defined paintInterior?
| @override | ||
| int get hashCode => Object.hash(borderSide, borderRadius, gapPadding); | ||
| } | ||
|
|
There was a problem hiding this comment.
Can you also add this new class to OutlineInputBorder 's "See also"?
|
Reverting my approval since I just realized that the Also I'd prefer @justinmc giving it a final look before landing. I'll let him know that this PR is ready for a final review. |
13a00d1 to
1d0e8df
Compare
| /// * [OutlineInputBorder], a traditional rounded rectangle border. | ||
| /// * [RoundedSuperellipseBorder], which can be used with this border for iOS-style shapes. | ||
| /// * [UnderlineInputBorder], the default [InputDecorator] border which | ||
| /// draws a horizontal line at the bottom of the input decorator's container. |
There was a problem hiding this comment.
Nit: I would swap the order of RoundedSuperellipseBorder and UnderlineInputBorder so that the two subclasses of InputBorder are next to each other.
| /// | ||
| /// * [InputDecoration.floatingLabelBehavior], which should be set to | ||
| /// [FloatingLabelBehavior.never] when the [borderSide] is | ||
| /// [BorderSide.none]. If let as [FloatingLabelBehavior.auto], the label |
There was a problem hiding this comment.
Would it be possible/useful to catch this with an assert in InputDecoration?
There was a problem hiding this comment.
This behaviour is specific to ShapedInputBorder, I don't think coupling that in InputDecoration will be a good idea. And since ShapedInputBorder don't have access to floatingLabelBehavior, its not feasible to assert this.
| // Create a continuous path for the border with a gap in the top edge. | ||
| final Path outerPath = shape.getOuterPath(rect, textDirection: textDirection); | ||
|
|
||
| // If there's no meaningful gap, return the full outline |
There was a problem hiding this comment.
Nit: Periods at the end of your comments here and elsewhere.
| // Create a continuous path for the border with a gap in the top edge. | ||
| final Path outerPath = shape.getOuterPath(rect, textDirection: textDirection); | ||
|
|
||
| // If there's no meaningful gap, return the full outline |
There was a problem hiding this comment.
Nit: Periods at the end of your comments here and elsewhere.
1d0e8df to
f31263f
Compare
Roll Flutter from dfd92b773219 to da72d5936d69 (39 revisions) flutter/flutter@dfd92b7...da72d59 2026-01-29 98614782+auto-submit[bot]@users.noreply.github.com Reverts "[ Tool / Engine ] Cleanup x86 references (#181152)" (flutter/flutter#181643) 2026-01-29 engine-flutter-autoroll@skia.org Roll Skia from 174db42b7300 to 89df65f8324c (2 revisions) (flutter/flutter#181636) 2026-01-29 59215665+davidhicks980@users.noreply.github.com [material/menu_anchor.dart] Add animations to MenuAnchor. (flutter/flutter#176494) 2026-01-28 engine-flutter-autoroll@skia.org Roll Skia from 8e09f8a82251 to 174db42b7300 (6 revisions) (flutter/flutter#181627) 2026-01-28 31859944+LongCatIsLooong@users.noreply.github.com Send statusBarTouch events via dedicated messages (flutter/flutter#179643) 2026-01-28 git@reb0.org test: Improve DropdownMenuFormField tests (flutter/flutter#181369) 2026-01-28 evanwall@buffalo.edu Account for vec3 padding in Metal (flutter/flutter#181563) 2026-01-28 bkonyi@google.com [ Tool / Engine ] Cleanup x86 references (flutter/flutter#181152) 2026-01-28 ybz975218925@gmail.com Fix the issue on macOS where, after a hot restart with multiple windows, unresponsive windows are left behind. (flutter/flutter#180287) 2026-01-28 engine-flutter-autoroll@skia.org Roll Skia from 675444e94bc9 to 8e09f8a82251 (7 revisions) (flutter/flutter#181606) 2026-01-28 engine-flutter-autoroll@skia.org Roll Packages from e37af11 to 1cb2148 (5 revisions) (flutter/flutter#181608) 2026-01-28 codefu@google.com fix: swap app and engine version in vk::ApplicationInfo (flutter/flutter#181432) 2026-01-28 30870216+gaaclarke@users.noreply.github.com Adds impeller backend to skia gold client (flutter/flutter#181503) 2026-01-28 mdebbar@google.com Remove chrome_and_driver dependency where it's not needed (flutter/flutter#178174) 2026-01-28 codefu@google.com chore: Windows_mokey basic_material_app_win__compile !bringup (flutter/flutter#180985) 2026-01-28 116356835+AbdeMohlbi@users.noreply.github.com Fix generating both `settings.gradle` and `settings.gradle.kts` for plugins (flutter/flutter#181592) 2026-01-28 engine-flutter-autoroll@skia.org Roll Skia from 6614f89de521 to 675444e94bc9 (3 revisions) (flutter/flutter#181587) 2026-01-28 104349824+huycozy@users.noreply.github.com Fix `todayBorder` todayBorder color is incorrectly overridden by `todayForegroundColor` in CalendarDatePicker (flutter/flutter#178792) 2026-01-28 engine-flutter-autoroll@skia.org Roll Skia from 8f1695a4b328 to 6614f89de521 (2 revisions) (flutter/flutter#181583) 2026-01-28 34465683+rkishan516@users.noreply.github.com feat: add RoundedSuperellipseInputBorder (flutter/flutter#177220) 2026-01-28 engine-flutter-autoroll@skia.org Roll Dart SDK from 38e351498549 to f10dcbfca98f (2 revisions) (flutter/flutter#181582) 2026-01-28 engine-flutter-autoroll@skia.org Roll Skia from f424d58e37a3 to 8f1695a4b328 (6 revisions) (flutter/flutter#181577) 2026-01-28 116356835+AbdeMohlbi@users.noreply.github.com Remove unused code paths in `PlatformViewsController.java` (flutter/flutter#181393) 2026-01-28 34465683+rkishan516@users.noreply.github.com feat: add onEnd to AnimatedCrossFade (flutter/flutter#181455) 2026-01-28 1961493+harryterkelsen@users.noreply.github.com Don't pass bounds to saveLayer call when painting ImageFilter (flutter/flutter#181353) 2026-01-28 luanpotter27@gmail.com test: Clarify failure messages on gestures/debug_test.dart (flutter/flutter#181109) 2026-01-27 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from akraNGn2lw4T1msgZ... to adhoq9ouVRh0xzkm3... (flutter/flutter#181571) 2026-01-27 engine-flutter-autoroll@skia.org Roll Dart SDK from 4c7cb0a1d07d to 38e351498549 (4 revisions) (flutter/flutter#181570) 2026-01-27 ahmedsameha1@gmail.com Make sure that an AnimatedPadding doesn't crash in 0x0 environment (flutter/flutter#181235) 2026-01-27 ahmedsameha1@gmail.com Make sure that an ImageFiltered doesn't crash at 0x0 environment (flutter/flutter#181067) 2026-01-27 magder@google.com Marks firebase_release_smoke_test to be unflaky (flutter/flutter#181308) 2026-01-27 kazbek.sultanov.doc@gmail.com Fix remove material import box decoration test (flutter/flutter#181253) 2026-01-27 engine-flutter-autoroll@skia.org Roll Skia from c2754838b077 to f424d58e37a3 (8 revisions) (flutter/flutter#181564) 2026-01-27 ahmedsameha1@gmail.com Make sure that an AnimatedAlign doesn't crash in 0x0 environment (flutter/flutter#181361) 2026-01-27 ahmedsameha1@gmail.com Make sure that an ImageIcon doesn't crash in 0x0 environment (flutter/flutter#181099) 2026-01-27 ahmedsameha1@gmail.com Make sure that an AnimatedContainer doesn't crash in 0x0 environment (flutter/flutter#181198) 2026-01-27 ahmedsameha1@gmail.com Make sure that an AnimatedRotation doesn't crash in 0x0 environment (flutter/flutter#181486) 2026-01-27 ahmedsameha1@gmail.com Make sure that an AnimatedPositionedDirectional doesn't crash in 0x0 … (flutter/flutter#181451) 2026-01-27 jacksongardner@google.com Merge changelog for 3.38.8. (flutter/flutter#181558) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC bmparr@google.com,stuartmorgan@google.com on the revert to ensure that a human is aware of the problem. ...
# Whats new * Add RoundedSuperellipseInputBorder fixes: flutter#176987 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing.
…r#10923) Roll Flutter from dfd92b773219 to da72d5936d69 (39 revisions) flutter/flutter@dfd92b7...da72d59 2026-01-29 98614782+auto-submit[bot]@users.noreply.github.com Reverts "[ Tool / Engine ] Cleanup x86 references (#181152)" (flutter/flutter#181643) 2026-01-29 engine-flutter-autoroll@skia.org Roll Skia from 174db42b7300 to 89df65f8324c (2 revisions) (flutter/flutter#181636) 2026-01-29 59215665+davidhicks980@users.noreply.github.com [material/menu_anchor.dart] Add animations to MenuAnchor. (flutter/flutter#176494) 2026-01-28 engine-flutter-autoroll@skia.org Roll Skia from 8e09f8a82251 to 174db42b7300 (6 revisions) (flutter/flutter#181627) 2026-01-28 31859944+LongCatIsLooong@users.noreply.github.com Send statusBarTouch events via dedicated messages (flutter/flutter#179643) 2026-01-28 git@reb0.org test: Improve DropdownMenuFormField tests (flutter/flutter#181369) 2026-01-28 evanwall@buffalo.edu Account for vec3 padding in Metal (flutter/flutter#181563) 2026-01-28 bkonyi@google.com [ Tool / Engine ] Cleanup x86 references (flutter/flutter#181152) 2026-01-28 ybz975218925@gmail.com Fix the issue on macOS where, after a hot restart with multiple windows, unresponsive windows are left behind. (flutter/flutter#180287) 2026-01-28 engine-flutter-autoroll@skia.org Roll Skia from 675444e94bc9 to 8e09f8a82251 (7 revisions) (flutter/flutter#181606) 2026-01-28 engine-flutter-autoroll@skia.org Roll Packages from e37af11 to 1cb2148 (5 revisions) (flutter/flutter#181608) 2026-01-28 codefu@google.com fix: swap app and engine version in vk::ApplicationInfo (flutter/flutter#181432) 2026-01-28 30870216+gaaclarke@users.noreply.github.com Adds impeller backend to skia gold client (flutter/flutter#181503) 2026-01-28 mdebbar@google.com Remove chrome_and_driver dependency where it's not needed (flutter/flutter#178174) 2026-01-28 codefu@google.com chore: Windows_mokey basic_material_app_win__compile !bringup (flutter/flutter#180985) 2026-01-28 116356835+AbdeMohlbi@users.noreply.github.com Fix generating both `settings.gradle` and `settings.gradle.kts` for plugins (flutter/flutter#181592) 2026-01-28 engine-flutter-autoroll@skia.org Roll Skia from 6614f89de521 to 675444e94bc9 (3 revisions) (flutter/flutter#181587) 2026-01-28 104349824+huycozy@users.noreply.github.com Fix `todayBorder` todayBorder color is incorrectly overridden by `todayForegroundColor` in CalendarDatePicker (flutter/flutter#178792) 2026-01-28 engine-flutter-autoroll@skia.org Roll Skia from 8f1695a4b328 to 6614f89de521 (2 revisions) (flutter/flutter#181583) 2026-01-28 34465683+rkishan516@users.noreply.github.com feat: add RoundedSuperellipseInputBorder (flutter/flutter#177220) 2026-01-28 engine-flutter-autoroll@skia.org Roll Dart SDK from 38e351498549 to f10dcbfca98f (2 revisions) (flutter/flutter#181582) 2026-01-28 engine-flutter-autoroll@skia.org Roll Skia from f424d58e37a3 to 8f1695a4b328 (6 revisions) (flutter/flutter#181577) 2026-01-28 116356835+AbdeMohlbi@users.noreply.github.com Remove unused code paths in `PlatformViewsController.java` (flutter/flutter#181393) 2026-01-28 34465683+rkishan516@users.noreply.github.com feat: add onEnd to AnimatedCrossFade (flutter/flutter#181455) 2026-01-28 1961493+harryterkelsen@users.noreply.github.com Don't pass bounds to saveLayer call when painting ImageFilter (flutter/flutter#181353) 2026-01-28 luanpotter27@gmail.com test: Clarify failure messages on gestures/debug_test.dart (flutter/flutter#181109) 2026-01-27 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from akraNGn2lw4T1msgZ... to adhoq9ouVRh0xzkm3... (flutter/flutter#181571) 2026-01-27 engine-flutter-autoroll@skia.org Roll Dart SDK from 4c7cb0a1d07d to 38e351498549 (4 revisions) (flutter/flutter#181570) 2026-01-27 ahmedsameha1@gmail.com Make sure that an AnimatedPadding doesn't crash in 0x0 environment (flutter/flutter#181235) 2026-01-27 ahmedsameha1@gmail.com Make sure that an ImageFiltered doesn't crash at 0x0 environment (flutter/flutter#181067) 2026-01-27 magder@google.com Marks firebase_release_smoke_test to be unflaky (flutter/flutter#181308) 2026-01-27 kazbek.sultanov.doc@gmail.com Fix remove material import box decoration test (flutter/flutter#181253) 2026-01-27 engine-flutter-autoroll@skia.org Roll Skia from c2754838b077 to f424d58e37a3 (8 revisions) (flutter/flutter#181564) 2026-01-27 ahmedsameha1@gmail.com Make sure that an AnimatedAlign doesn't crash in 0x0 environment (flutter/flutter#181361) 2026-01-27 ahmedsameha1@gmail.com Make sure that an ImageIcon doesn't crash in 0x0 environment (flutter/flutter#181099) 2026-01-27 ahmedsameha1@gmail.com Make sure that an AnimatedContainer doesn't crash in 0x0 environment (flutter/flutter#181198) 2026-01-27 ahmedsameha1@gmail.com Make sure that an AnimatedRotation doesn't crash in 0x0 environment (flutter/flutter#181486) 2026-01-27 ahmedsameha1@gmail.com Make sure that an AnimatedPositionedDirectional doesn't crash in 0x0 … (flutter/flutter#181451) 2026-01-27 jacksongardner@google.com Merge changelog for 3.38.8. (flutter/flutter#181558) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC bmparr@google.com,stuartmorgan@google.com on the revert to ensure that a human is aware of the problem. ...
Whats new
fixes: #176987
Pre-launch Checklist
///).