Beyond Rounded Rectangles: ShapedInputBorder for Sophisticated Flutter UIs
Flutter 3.44 introduced ShapedInputBorder, letting any ShapeBorder become a TextField border while keeping the floating-label gap intact.
Published on • October 7, 2026
AI Assistant

For years, Material text fields in Flutter had exactly two border options: OutlineInputBorder (a rounded rectangle) and UnderlineInputBorder (a line). If your design system wanted a stadium pill, a beveled corner, or the continuous-corner “squircle” that iOS uses everywhere, you had to fight the framework — subclass InputBorder, reimplement the floating-label gap, or abandon InputDecoration entirely.
Flutter 3.44 fixed this with a small, surgical API addition: ShapedInputBorder.
What ShapedInputBorder Does
ShapedInputBorder is a new InputBorder subclass that accepts any ShapeBorder as the outline of an InputDecorator. From the API docs: it “draws a custom shape around an InputDecorator’s container,” allowing any ShapeBorder to be used as an input decorator border while maintaining the gap functionality for floating labels.
That last clause is the whole point. The floating-label gap — the notch in the outline where the label sits when focused — is the fiddly part of reimplementing an input border. ShapedInputBorder handles it for you, so your custom shape and Material’s label choreography coexist.
The constructor is minimal:
const ShapedInputBorder({
super.borderSide = const BorderSide(),
required this.shape,
this.gapPadding = 4.0,
}) : assert(gapPadding >= 0.0);
shape— anyShapeBorder:RoundedSuperellipseBorder,StadiumBorder,BeveledRectangleBorder, or your own subclass.borderSide— the stroke. PassBorderSide.noneto draw no line; the shape still fills whenInputDecoration.filledistrue.gapPadding— horizontal padding around the floating-label gap (default4.0).
It landed in PR #177220 and ships in Flutter 3.44.
A Practical Example: iOS-Style Continuous Corners
The most common motivation is RoundedSuperellipseBorder — the superellipse corner that Apple calls “continuous” and designers call a squircle. Standard BorderRadius.circular corners have a visible tangent discontinuity; superellipse corners flow smoothly, which is why they look calmer at large radii.
TextField(
decoration: InputDecoration(
filled: true,
fillColor: Theme.of(context).colorScheme.surfaceContainerHighest,
labelText: 'Email',
border: ShapedInputBorder(
shape: RoundedSuperellipseBorder(
borderRadius: BorderRadius.circular(16),
),
),
),
)
The same pattern works for a stadium-shaped search field:
ShapedInputBorder(
shape: const StadiumBorder(),
borderSide: BorderSide(
color: Theme.of(context).colorScheme.outline,
width: 1.5,
),
)
Behaviors Worth Knowing
BorderSide.none still shows the fill. If you pass borderSide: BorderSide.none, no stroke is drawn, but when filled: true the shape’s interior is painted. This gives you “outline-free” filled fields with non-rectangular silhouettes. In that mode, set FloatingLabelBehavior.never — there’s no line for the label to notch into.
You don’t have to supply borderSide at all. If you omit it, the InputDecorator substitutes one via copyWith, derived from the theme and whether the field is focused. That means focused/unfocused color transitions keep working the way they do with OutlineInputBorder.
Transitions animate. ShapedInputBorder implements lerpFrom/lerpTo, so swapping border shapes or animating between states produces smooth interpolation rather than a hard cut.
The inheritance chain is short: Object → ShapeBorder → InputBorder → ShapedInputBorder. If you’ve ever written a custom InputBorder, most of that work now comes for free.
Where This Fits in Flutter 3.44+
Flutter 3.44 also added CupertinoFocusHalo superellipse support, signaling a broader push toward continuous-corner geometry across both design systems. Notably, Material and Cupertino were frozen in 3.44 and are moving toward the standalone material_ui and cupertino_ui packages — so APIs like this one increasingly ship on their own cadence rather than waiting for a full SDK release.
That’s good news for design-system work: if you maintain a custom look built on Flutter primitives, ShapedInputBorder is one less layer you need to fork.
Gotchas
- A
GlobalKeyisn’t involved here, but rebuildingInputDecorationevery frame will thrash paint. Build yourShapedInputBorderonce (e.g. as a field) if the shape is static. gapPaddingmust be>= 0.0— the assert fires in debug mode if you pass a negative value.- For very complex custom
ShapeBorders, remember the outline still needs a hole for the floating label. Test withFloatingLabelBehavior.autobefore shipping.
Further Reading
- What’s New in Flutter 3.44
ShapedInputBorderAPI referenceRoundedSuperellipseBorderflutter create --sample=material.ShapedInputBorder.1 mysamplefor the official runnable sample