Unverified Commit f5ce6389 authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Add Directionality.maybeOf (#69117)

parent 48a9fc13
......@@ -1834,7 +1834,7 @@ class _RawChipState extends State<RawChip> with TickerProviderStateMixin<RawChip
final ThemeData theme = Theme.of(context)!;
final ChipThemeData chipTheme = ChipTheme.of(context);
final TextDirection? textDirection = Directionality.of(context);
final TextDirection? textDirection = Directionality.maybeOf(context);
final ShapeBorder shape = widget.shape ?? chipTheme.shape;
final double elevation = widget.elevation ?? chipTheme.elevation ?? _defaultElevation;
final double pressElevation = widget.pressElevation ?? chipTheme.pressElevation ?? _defaultPressElevation;
......
......@@ -469,7 +469,7 @@ class AlertDialog extends StatelessWidget {
// The paddingScaleFactor is used to adjust the padding of Dialog's
// children.
final double paddingScaleFactor = _paddingScaleFactor(MediaQuery.of(context)!.textScaleFactor);
final TextDirection? textDirection = Directionality.of(context);
final TextDirection? textDirection = Directionality.maybeOf(context);
Widget? titleWidget;
Widget? contentWidget;
......@@ -826,7 +826,7 @@ class SimpleDialog extends StatelessWidget {
// The paddingScaleFactor is used to adjust the padding of Dialog
// children.
final double paddingScaleFactor = _paddingScaleFactor(MediaQuery.of(context)!.textScaleFactor);
final TextDirection? textDirection = Directionality.of(context);
final TextDirection? textDirection = Directionality.maybeOf(context);
Widget? titleWidget;
if (title != null) {
......
......@@ -499,11 +499,11 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
Widget _buildDrawer(BuildContext context) {
final bool drawerIsStart = widget.alignment == DrawerAlignment.start;
final EdgeInsets padding = MediaQuery.of(context)!.padding;
final TextDirection? textDirection = Directionality.of(context);
final TextDirection textDirection = Directionality.of(context)!;
double? dragAreaWidth = widget.edgeDragWidth;
if (widget.edgeDragWidth == null) {
switch (textDirection!) {
switch (textDirection) {
case TextDirection.ltr:
dragAreaWidth = _kEdgeDragWidth +
(drawerIsStart ? padding.left : padding.right);
......
......@@ -564,7 +564,7 @@ class _DropdownRoutePage<T> extends StatelessWidget {
route.scrollController = ScrollController(initialScrollOffset: menuLimits.scrollOffset);
}
final TextDirection? textDirection = Directionality.of(context);
final TextDirection? textDirection = Directionality.maybeOf(context);
final Widget menu = _DropdownMenu<T>(
route: route,
padding: padding.resolve(textDirection),
......@@ -1178,7 +1178,7 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
void _handleTap() {
final RenderBox itemBox = context.findRenderObject()! as RenderBox;
final Rect itemRect = itemBox.localToGlobal(Offset.zero) & itemBox.size;
final TextDirection? textDirection = Directionality.of(context);
final TextDirection? textDirection = Directionality.maybeOf(context);
final EdgeInsetsGeometry menuMargin = ButtonTheme.of(context).alignedDropdown
? _kAlignedMenuMargin
: _kUnalignedMenuMargin;
......
......@@ -453,7 +453,7 @@ class _MaterialState extends State<Material> with TickerProviderStateMixin {
child: child,
clipper: ShapeBorderClipper(
shape: shape,
textDirection: Directionality.of(context),
textDirection: Directionality.maybeOf(context),
),
clipBehavior: clipBehavior,
);
......@@ -787,7 +787,7 @@ class _MaterialInteriorState extends AnimatedWidgetBaseState<_MaterialInterior>
),
clipper: ShapeBorderClipper(
shape: shape,
textDirection: Directionality.of(context),
textDirection: Directionality.maybeOf(context),
),
clipBehavior: widget.clipBehavior,
elevation: elevation,
......@@ -812,8 +812,8 @@ class _ShapeBorderPaint extends StatelessWidget {
Widget build(BuildContext context) {
return CustomPaint(
child: child,
painter: borderOnForeground ? null : _ShapeBorderPainter(shape, Directionality.of(context)),
foregroundPainter: borderOnForeground ? _ShapeBorderPainter(shape, Directionality.of(context)) : null,
painter: borderOnForeground ? null : _ShapeBorderPainter(shape, Directionality.maybeOf(context)),
foregroundPainter: borderOnForeground ? _ShapeBorderPainter(shape, Directionality.maybeOf(context)) : null,
);
}
}
......
......@@ -494,7 +494,7 @@ class _MonthPickerState extends State<_MonthPicker> {
late DateTime _previousMonthDate;
PageController? _pageController;
late MaterialLocalizations _localizations;
TextDirection? _textDirection;
late TextDirection _textDirection;
Map<LogicalKeySet, Intent>? _shortcutMap;
Map<Type, Action<Intent>>? _actionMap;
FocusNode? _dayGridFocus;
......@@ -525,7 +525,7 @@ class _MonthPickerState extends State<_MonthPicker> {
void didChangeDependencies() {
super.didChangeDependencies();
_localizations = MaterialLocalizations.of(context);
_textDirection = Directionality.of(context);
_textDirection = Directionality.of(context)!;
}
@override
......@@ -595,7 +595,7 @@ class _MonthPickerState extends State<_MonthPicker> {
if (!_isDisplayingLastMonth) {
SemanticsService.announce(
_localizations.formatMonthYear(_nextMonthDate),
_textDirection!,
_textDirection,
);
_pageController!.nextPage(
duration: _monthScrollDuration,
......@@ -609,7 +609,7 @@ class _MonthPickerState extends State<_MonthPicker> {
if (!_isDisplayingFirstMonth) {
SemanticsService.announce(
_localizations.formatMonthYear(_previousMonthDate),
_textDirection!,
_textDirection,
);
_pageController!.previousPage(
duration: _monthScrollDuration,
......
......@@ -707,7 +707,7 @@ class _MonthItemState extends State<_MonthItem> {
final ColorScheme colorScheme = theme.colorScheme;
final TextTheme textTheme = theme.textTheme;
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final TextDirection? textDirection = Directionality.of(context);
final TextDirection textDirection = Directionality.of(context)!;
final Color highlightColor = _highlightColor(context);
final int day = dayToBuild.day;
......
......@@ -116,7 +116,7 @@ class AnimatedSize extends SingleChildRenderObjectWidget {
reverseDuration: reverseDuration,
curve: curve,
vsync: vsync,
textDirection: Directionality.of(context),
textDirection: Directionality.maybeOf(context),
clipBehavior: clipBehavior,
);
}
......@@ -129,7 +129,7 @@ class AnimatedSize extends SingleChildRenderObjectWidget {
..reverseDuration = reverseDuration
..curve = curve
..vsync = vsync
..textDirection = Directionality.of(context)
..textDirection = Directionality.maybeOf(context)
..clipBehavior = clipBehavior;
}
......
......@@ -107,11 +107,28 @@ class Directionality extends InheritedWidget {
/// ```dart
/// TextDirection textDirection = Directionality.of(context);
/// ```
// TODO(goderbauer): Make this non-null when customers have upgraded to Directionality.maybeOf.
static TextDirection? of(BuildContext context) {
final Directionality? widget = context.dependOnInheritedWidgetOfExactType<Directionality>();
return widget?.textDirection;
}
/// The text direction from the closest instance of this class that encloses
/// the given context.
///
/// If there is no [Directionality] ancestor widget in the tree at the given
/// context, then this will return null.
///
/// Typical usage is as follows:
///
/// ```dart
/// TextDirection? textDirection = Directionality.maybeOf(context);
/// ```
static TextDirection? maybeOf(BuildContext context) {
final Directionality? widget = context.dependOnInheritedWidgetOfExactType<Directionality>();
return widget?.textDirection;
}
@override
bool updateShouldNotify(Directionality oldWidget) => textDirection != oldWidget.textDirection;
......@@ -831,7 +848,7 @@ class ClipPath extends SingleChildRenderObjectWidget {
return ClipPath(
clipper: ShapeBorderClipper(
shape: shape,
textDirection: Directionality.of(context),
textDirection: Directionality.maybeOf(context),
),
clipBehavior: clipBehavior,
child: child,
......@@ -1258,7 +1275,7 @@ class Transform extends SingleChildRenderObjectWidget {
transform: transform,
origin: origin,
alignment: alignment,
textDirection: Directionality.of(context),
textDirection: Directionality.maybeOf(context),
transformHitTests: transformHitTests,
);
}
......@@ -1269,7 +1286,7 @@ class Transform extends SingleChildRenderObjectWidget {
..transform = transform
..origin = origin
..alignment = alignment
..textDirection = Directionality.of(context)
..textDirection = Directionality.maybeOf(context)
..transformHitTests = transformHitTests;
}
}
......@@ -1495,7 +1512,7 @@ class FittedBox extends SingleChildRenderObjectWidget {
return RenderFittedBox(
fit: fit,
alignment: alignment,
textDirection: Directionality.of(context),
textDirection: Directionality.maybeOf(context),
clipBehavior: clipBehavior,
);
}
......@@ -1505,7 +1522,7 @@ class FittedBox extends SingleChildRenderObjectWidget {
renderObject
..fit = fit
..alignment = alignment
..textDirection = Directionality.of(context)
..textDirection = Directionality.maybeOf(context)
..clipBehavior = clipBehavior;
}
......@@ -1689,7 +1706,7 @@ class Padding extends SingleChildRenderObjectWidget {
RenderPadding createRenderObject(BuildContext context) {
return RenderPadding(
padding: padding,
textDirection: Directionality.of(context),
textDirection: Directionality.maybeOf(context),
);
}
......@@ -1697,7 +1714,7 @@ class Padding extends SingleChildRenderObjectWidget {
void updateRenderObject(BuildContext context, RenderPadding renderObject) {
renderObject
..padding = padding
..textDirection = Directionality.of(context);
..textDirection = Directionality.maybeOf(context);
}
@override
......@@ -1884,7 +1901,7 @@ class Align extends SingleChildRenderObjectWidget {
alignment: alignment,
widthFactor: widthFactor,
heightFactor: heightFactor,
textDirection: Directionality.of(context),
textDirection: Directionality.maybeOf(context),
);
}
......@@ -1894,7 +1911,7 @@ class Align extends SingleChildRenderObjectWidget {
..alignment = alignment
..widthFactor = widthFactor
..heightFactor = heightFactor
..textDirection = Directionality.of(context);
..textDirection = Directionality.maybeOf(context);
}
@override
......@@ -2334,7 +2351,7 @@ class UnconstrainedBox extends SingleChildRenderObjectWidget {
@override
void updateRenderObject(BuildContext context, covariant RenderUnconstrainedBox renderObject) {
renderObject
..textDirection = textDirection ?? Directionality.of(context)
..textDirection = textDirection ?? Directionality.maybeOf(context)
..alignment = alignment
..constrainedAxis = constrainedAxis
..clipBehavior = clipBehavior;
......@@ -2342,7 +2359,7 @@ class UnconstrainedBox extends SingleChildRenderObjectWidget {
@override
RenderUnconstrainedBox createRenderObject(BuildContext context) => RenderUnconstrainedBox(
textDirection: textDirection ?? Directionality.of(context),
textDirection: textDirection ?? Directionality.maybeOf(context),
alignment: alignment,
constrainedAxis: constrainedAxis,
clipBehavior: clipBehavior,
......@@ -2431,7 +2448,7 @@ class FractionallySizedBox extends SingleChildRenderObjectWidget {
alignment: alignment,
widthFactor: widthFactor,
heightFactor: heightFactor,
textDirection: Directionality.of(context),
textDirection: Directionality.maybeOf(context),
);
}
......@@ -2441,7 +2458,7 @@ class FractionallySizedBox extends SingleChildRenderObjectWidget {
..alignment = alignment
..widthFactor = widthFactor
..heightFactor = heightFactor
..textDirection = Directionality.of(context);
..textDirection = Directionality.maybeOf(context);
}
@override
......@@ -2594,7 +2611,7 @@ class OverflowBox extends SingleChildRenderObjectWidget {
maxWidth: maxWidth,
minHeight: minHeight,
maxHeight: maxHeight,
textDirection: Directionality.of(context),
textDirection: Directionality.maybeOf(context),
);
}
......@@ -2606,7 +2623,7 @@ class OverflowBox extends SingleChildRenderObjectWidget {
..maxWidth = maxWidth
..minHeight = minHeight
..maxHeight = maxHeight
..textDirection = Directionality.of(context);
..textDirection = Directionality.maybeOf(context);
}
@override
......@@ -3400,7 +3417,7 @@ class Stack extends MultiChildRenderObjectWidget {
assert(_debugCheckHasDirectionality(context));
return RenderStack(
alignment: alignment,
textDirection: textDirection ?? Directionality.of(context),
textDirection: textDirection ?? Directionality.maybeOf(context),
fit: fit,
clipBehavior: overflow == Overflow.visible ? Clip.none : clipBehavior,
);
......@@ -3411,7 +3428,7 @@ class Stack extends MultiChildRenderObjectWidget {
assert(_debugCheckHasDirectionality(context));
renderObject
..alignment = alignment
..textDirection = textDirection ?? Directionality.of(context)
..textDirection = textDirection ?? Directionality.maybeOf(context)
..fit = fit
..clipBehavior = overflow == Overflow.visible ? Clip.none : clipBehavior;
}
......@@ -3461,7 +3478,7 @@ class IndexedStack extends Stack {
return RenderIndexedStack(
index: index,
alignment: alignment,
textDirection: textDirection ?? Directionality.of(context),
textDirection: textDirection ?? Directionality.maybeOf(context),
);
}
......@@ -3471,7 +3488,7 @@ class IndexedStack extends Stack {
renderObject
..index = index
..alignment = alignment
..textDirection = textDirection ?? Directionality.of(context);
..textDirection = textDirection ?? Directionality.maybeOf(context);
}
}
......@@ -4084,7 +4101,7 @@ class Flex extends MultiChildRenderObjectWidget {
/// the logic for providing a text direction only when it is necessary.
@protected
TextDirection? getEffectiveTextDirection(BuildContext context) {
return textDirection ?? (_needTextDirection ? Directionality.of(context) : null);
return textDirection ?? (_needTextDirection ? Directionality.maybeOf(context) : null);
}
@override
......@@ -4954,7 +4971,7 @@ class Wrap extends MultiChildRenderObjectWidget {
runAlignment: runAlignment,
runSpacing: runSpacing,
crossAxisAlignment: crossAxisAlignment,
textDirection: textDirection ?? Directionality.of(context),
textDirection: textDirection ?? Directionality.maybeOf(context),
verticalDirection: verticalDirection,
clipBehavior: clipBehavior,
);
......@@ -4969,7 +4986,7 @@ class Wrap extends MultiChildRenderObjectWidget {
..runAlignment = runAlignment
..runSpacing = runSpacing
..crossAxisAlignment = crossAxisAlignment
..textDirection = textDirection ?? Directionality.of(context)
..textDirection = textDirection ?? Directionality.maybeOf(context)
..verticalDirection = verticalDirection
..clipBehavior = clipBehavior;
}
......@@ -6879,7 +6896,7 @@ class Semantics extends SingleChildRenderObjectWidget {
if (!containsText)
return null;
return Directionality.of(context);
return Directionality.maybeOf(context);
}
@override
......
......@@ -406,7 +406,7 @@ class Container extends StatelessWidget {
assert(decoration != null);
current = ClipPath(
clipper: _DecorationClipper(
textDirection: Directionality.of(context),
textDirection: Directionality.maybeOf(context),
decoration: decoration!,
),
clipBehavior: clipBehavior,
......
......@@ -52,7 +52,7 @@ ImageConfiguration createLocalImageConfiguration(BuildContext context, { Size? s
bundle: DefaultAssetBundle.of(context),
devicePixelRatio: MediaQuery.of(context, nullOk: true)?.devicePixelRatio ?? 1.0,
locale: Localizations.localeOf(context, nullOk: true),
textDirection: Directionality.of(context),
textDirection: Directionality.maybeOf(context),
size: size,
platform: defaultTargetPlatform,
);
......
......@@ -55,11 +55,29 @@ void main() {
bool good = false;
await tester.pumpWidget(Builder(
builder: (BuildContext context) {
expect(Directionality.of(context), isNull);
expect(Directionality.maybeOf(context), isNull);
good = true;
return const Placeholder();
},
));
expect(good, isTrue);
});
testWidgets('Directionality.maybeOf', (WidgetTester tester) async {
final GlobalKey hasDirectionality = GlobalKey();
final GlobalKey noDirectionality = GlobalKey();
await tester.pumpWidget(
Container(
key: noDirectionality,
child: Directionality(
textDirection: TextDirection.rtl,
child: Container(
key: hasDirectionality,
),
)
)
);
expect(Directionality.maybeOf(noDirectionality.currentContext!), isNull);
expect(Directionality.maybeOf(hasDirectionality.currentContext!), TextDirection.rtl);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment