-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
Use case
Summary: Add convenience const constructors to EdgeInsets:
- a general constructor to set a default for most sides (
EdgeInsets.someorEdgeInsets.except), and - four single-side convenience constructors:
EdgeInsets.exceptTop,EdgeInsets.exceptLeft,EdgeInsets.exceptRight,EdgeInsets.exceptBottom.
These reduce boilerplate in patterns like “padding 16 all around except top = 8” while remaining const and simple.
Motivation
Common patterns:
EdgeInsets.all(16)— same on all sidesEdgeInsets.only(top: 8, left: 16, right: 16, bottom: 16)— “all except top” (verbose)EdgeInsets.all(16).copyWith(top: 8)— notconst
New constructors express intent more clearly and provide const sugar.
We propose small, explicit constructors that let you express intent directly and keep const contexts:
-
EdgeInsets.some(rest: 16, top: 8)— set rest = 16 for unspecified sides, override top -
EdgeInsets.exceptTop(16)— set 16 for left/right/bottom, top = 0 (orEdgeInsets.exceptTop(16, 8)to set top = 8)
These are trivial wrappers around EdgeInsets.only(...) so there is zero runtime overhead.
Proposal
Proposed API
EdgeInsets.some
/// Creates edge insets where `rest` is applied to unspecified sides,
/// and any explicitly provided sides override `rest`.
///
/// Example:
/// EdgeInsets.some(rest: 16, top: 8) // top=8, left/right/bottom=16
const EdgeInsets.some({
double rest = 0.0,
double? left,
double? top,
double? right,
double? bottom,
});
Single-side convenience constructors
/// Apply [value] to left/right/bottom; top defaults to 0.0 or can be overridden.
const EdgeInsets.exceptTop(double value, [double top = 0.0]);
/// Apply [value] to top/right/bottom; left defaults to 0.0 or can be overridden.
const EdgeInsets.exceptLeft(double value, [double left = 0.0]);
/// Apply [value] to left/top/bottom; right defaults to 0.0 or can be overridden.
const EdgeInsets.exceptRight(double value, [double right = 0.0]);
/// Apply [value] to left/top/right; bottom defaults to 0.0 or can be overridden.
const EdgeInsets.exceptBottom(double value, [double bottom = 0.0]);Directional variants (for RTL-aware code)
Add mirror constructors to EdgeInsetsDirectional:
const EdgeInsetsDirectional.some({
double rest = 0.0,
double? start,
double? top,
double? end,
double? bottom,
});
const EdgeInsetsDirectional.exceptStart(double value, [double start = 0.0]);
const EdgeInsetsDirectional.exceptEnd(double value, [double end = 0.0]);Implementation Sketch
Add these constructors in edge_insets.dart inside class EdgeInsets (trivial forwarding to only keeps const):
// General
const EdgeInsets.some({
double rest = 0.0,
double? left,
double? top,
double? right,
double? bottom,
}) : this.only(
left: left ?? rest,
top: top ?? rest,
right: right ?? rest,
bottom: bottom ?? rest,
);
const EdgeInsets.except({
double value = 0.0,
double? left,
double? top,
double? right,
double? bottom,
}) : this.only(
left: left ?? value,
top: top ?? value,
right: right ?? value,
bottom: bottom ?? value,
);
// Single-side helpers
const EdgeInsets.exceptTop(double value, [double top = 0.0])
: this.only(left: value, top: top, right: value, bottom: value);
const EdgeInsets.exceptLeft(double value, [double left = 0.0])
: this.only(left: left, top: value, right: value, bottom: value);
const EdgeInsets.exceptRight(double value, [double right = 0.0])
: this.only(left: value, top: value, right: right, bottom: value);
const EdgeInsets.exceptBottom(double value, [double bottom = 0.0])
: this.only(left: value, top: value, right: value, bottom: bottom);Directional variants (in EdgeInsetsDirectional):
const EdgeInsetsDirectional.some({
double rest = 0.0,
double? start,
double? top,
double? end,
double? bottom,
}) : this.only(
start: start ?? rest,
top: top ?? rest,
end: end ?? rest,
bottom: bottom ?? rest,
);
const EdgeInsetsDirectional.exceptStart(double value, [double start = 0.0])
: this.only(start: start, top: value, end: value, bottom: value);
const EdgeInsetsDirectional.exceptEnd(double value, [double end = 0.0])
: this.only(start: value, top: value, end: end, bottom: value);
Implementation note: These constructors are pure sugar and compile to EdgeInsets.only, so they have no runtime allocation cost beyond what EdgeInsets.only already h
Tests
void main() {
test('EdgeInsets.some uses rest for unspecified sides', () {
const e = EdgeInsets.some(rest: 10, top: 4);
expect(e.left, 10);
expect(e.right, 10);
expect(e.bottom, 10);
expect(e.top, 4);
});
test('EdgeInsets.except equals equivalent EdgeInsets.only', () {
const a = EdgeInsets.except(value: 16, top: 8);
const b = EdgeInsets.only(left: 16, top: 8, right: 16, bottom: 16);
expect(a, equals(b));
});
test('EdgeInsets.exceptTop single-arg equals expected values', () {
const e = EdgeInsets.exceptTop(12);
expect(e.left, 12);
expect(e.right, 12);
expect(e.bottom, 12);
expect(e.top, 0);
});
test('EdgeInsets.exceptTop with override', () {
const e = EdgeInsets.exceptTop(20, 6);
const expected = EdgeInsets.only(left: 20, top: 6, right: 20, bottom: 20);
expect(e, equals(expected));
});
test('EdgeInsetsDirectional.some resolves correctly LTR/RTL', () {
const d = EdgeInsetsDirectional.some(rest: 8, start: 4);
final resolvedLTR = d.resolve(TextDirection.ltr);
expect(resolvedLTR.left, 4);
expect(resolvedLTR.right, 8);
final resolvedRTL = d.resolve(TextDirection.rtl);
expect(resolvedRTL.left, 8);
expect(resolvedRTL.right, 4);
});
test('except helpers are const-constructible', () {
const p = EdgeInsets.exceptLeft(8, 0);
expect(p, isNotNull);
});
}Backwards compatibility & design notes
-
Additive change: these constructors are new, do not change any existing API semantics.
-
constconstructors preserve compile-time construction. -
The constructors are thin wrappers (delegate to
EdgeInsets.only) — trivial to review and low risk. -
Directional variants handle RTL via the existing
resolvemachinery.
Request for Assignment
I would like to contribute this feature to Flutter by implementing it myself.
If this proposal is accepted, I kindly request the Flutter team to assign this issue to me so I can begin working on the implementation and submit a PR.
Next steps I can help with
- Draft a PR patch (code + tests) you can apply to a fork.
- Draft the GitHub issue text ready to post (or comment on an existing issue).
- Implement the EdgeInsetsDirectional variants as well.