Skip to content

Commit 6bc5bb6

Browse files
Copilotbdlukaa
andauthored
fix: NavigationView compact pane PaneItemExpander flyout size and position (#1310)
* Initial plan * fix: NavigationView compact pane flyout placement in RTL directionality Co-authored-by: bdlukaa <45696119+bdlukaa@users.noreply.github.com> * fix: correct flyout leftTop/rightTop vertical alignment when flyout is tall Co-authored-by: bdlukaa <45696119+bdlukaa@users.noreply.github.com> * chore: Linting --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: bdlukaa <45696119+bdlukaa@users.noreply.github.com> Co-authored-by: Bruno D'Luka <brunodlukaa@gmail.com>
1 parent 169fa1f commit 6bc5bb6

23 files changed

+260
-241
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
- **BREAKING** feat: `TreeViewItem.children` is now unmodifiable. Use `TreeViewController` methods (`addItem()`, `addItems()`, `removeItem()`, `moveItem()`) to modify tree structure.
1515
- feat: `TitleBar` now supports double-click callback to maximize or restore the window ([#1298](https://github.com/bdlukaa/fluent_ui/issues/1298))
1616
- fix: Correctly apply `TitleBar`'s `isBackButtonEnabled` ([#1298](https://github.com/bdlukaa/fluent_ui/issues/1298))
17+
- fix: `NavigationView` compact pane `PaneItemExpander` flyout is now correctly placed in right-to-left directionality; Flyout `leftTop` and `rightTop` placement modes now correctly align with the top of the target element when the flyout is taller than the available space above the target ([#1289](https://github.com/bdlukaa/fluent_ui/issues/1289))
1718

1819
## 4.14.0
1920

example/lib/screens/navigation/tree_view.dart

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -329,30 +329,27 @@ TreeView(
329329
await Future<void>.delayed(const Duration(seconds: 2));
330330

331331
// ...and add the fetched nodes via the controller.
332-
_lazyController.addItems(
333-
[
334-
TreeViewItem(
335-
content: const Text('Lazy item 1'),
336-
value: 'lazy_1',
337-
),
338-
TreeViewItem(
339-
content: const Text('Lazy item 2'),
340-
value: 'lazy_2',
341-
),
342-
TreeViewItem(
343-
content: const Text('Lazy item 3'),
344-
value: 'lazy_3',
345-
),
346-
TreeViewItem(
347-
content: const Text(
348-
'Lazy item 4 (this text should not overflow)',
349-
overflow: TextOverflow.ellipsis,
350-
),
351-
value: 'lazy_4',
332+
_lazyController.addItems([
333+
TreeViewItem(
334+
content: const Text('Lazy item 1'),
335+
value: 'lazy_1',
336+
),
337+
TreeViewItem(
338+
content: const Text('Lazy item 2'),
339+
value: 'lazy_2',
340+
),
341+
TreeViewItem(
342+
content: const Text('Lazy item 3'),
343+
value: 'lazy_3',
344+
),
345+
TreeViewItem(
346+
content: const Text(
347+
'Lazy item 4 (this text should not overflow)',
348+
overflow: TextOverflow.ellipsis,
352349
),
353-
],
354-
parent: item,
355-
);
350+
value: 'lazy_4',
351+
),
352+
], parent: item);
356353
},
357354
onItemInvoked: (final item, final reason) async =>
358355
debugPrint('onItemInvoked(reason=$reason): $item'),

lib/src/controls/flyouts/flyout.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ class _FlyoutPositionDelegate extends SingleChildLayoutDelegate {
521521

522522
final bottomY = clampVertical(targetOffset.dy);
523523

524-
final horizontalTopY = clampVertical(topY + flyoutSize.height);
524+
final horizontalTopY = clampVertical(targetOffset.dy - targetSize.height);
525525
final horizontalY = clampVertical(
526526
targetOffset.dy - targetSize.height / 2 - flyoutSize.height / 2,
527527
);

lib/src/controls/flyouts/menu_bar.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,10 @@ class MenuBarState extends State<MenuBar> {
220220
onTapOutside: (_) => closeFlyout(),
221221
child: Container(
222222
constraints: BoxConstraints(
223-
minHeight: (40 + theme.visualDensity.baseSizeAdjustment.dy).clamp(0.0, double.infinity),
223+
minHeight: (40 + theme.visualDensity.baseSizeAdjustment.dy).clamp(
224+
0.0,
225+
double.infinity,
226+
),
224227
),
225228
padding: EdgeInsetsDirectional.only(
226229
top: barMargin.top,

lib/src/controls/flyouts/tooltip.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,10 @@ class TooltipThemeData with Diagnosticable {
736736
/// Creates the standard [TooltipThemeData] based on the given [theme].
737737
factory TooltipThemeData.standard(FluentThemeData theme) {
738738
return TooltipThemeData(
739-
height: (32 + theme.visualDensity.baseSizeAdjustment.dy).clamp(0.0, double.infinity),
739+
height: (32 + theme.visualDensity.baseSizeAdjustment.dy).clamp(
740+
0.0,
741+
double.infinity,
742+
),
740743
verticalOffset: 24,
741744
preferBelow: false,
742745
margin: EdgeInsetsDirectional.zero,

lib/src/controls/form/combo_box.dart

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -789,11 +789,17 @@ class _ComboBoxItemContainer extends StatelessWidget {
789789
: theme.resources.textFillColorPrimary;
790790

791791
final densityAdjustment = theme.visualDensity.baseSizeAdjustment.dy;
792-
final adjustedItemHeight = (kComboBoxItemHeight + densityAdjustment).clamp(0.0, double.infinity);
792+
final adjustedItemHeight = (kComboBoxItemHeight + densityAdjustment).clamp(
793+
0.0,
794+
double.infinity,
795+
);
793796
return Container(
794797
height: hasPadding
795798
? adjustedItemHeight
796-
: (adjustedItemHeight - _kMenuItemBottomPadding).clamp(0.0, double.infinity),
799+
: (adjustedItemHeight - _kMenuItemBottomPadding).clamp(
800+
0.0,
801+
double.infinity,
802+
),
797803
alignment: AlignmentDirectional.centerStart,
798804
child: DefaultTextStyle.merge(
799805
style: TextStyle(color: foregroundColor),

lib/src/controls/form/number_box.dart

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,10 @@ class NumberBoxState<T extends num> extends State<NumberBox<T>> {
546546
if (boxContext == null) return const SizedBox.shrink();
547547
final box = boxContext.findRenderObject()! as RenderBox;
548548
final isRtl = Directionality.of(context) == TextDirection.rtl;
549-
final overlayHeight = (kNumberBoxOverlayHeight + FluentTheme.of(context).visualDensity.baseSizeAdjustment.dy).clamp(0.0, double.infinity);
549+
final overlayHeight =
550+
(kNumberBoxOverlayHeight +
551+
FluentTheme.of(context).visualDensity.baseSizeAdjustment.dy)
552+
.clamp(0.0, double.infinity);
550553

551554
final Widget child = PositionedDirectional(
552555
width: kNumberBoxOverlayWidth,
@@ -907,7 +910,9 @@ class _NumberBoxCompactOverlay extends StatelessWidget {
907910
Widget build(BuildContext context) {
908911
assert(debugCheckHasFluentTheme(context));
909912
final theme = FluentTheme.of(context);
910-
final overlayHeight = (kNumberBoxOverlayHeight + theme.visualDensity.baseSizeAdjustment.dy).clamp(0.0, double.infinity);
913+
final overlayHeight =
914+
(kNumberBoxOverlayHeight + theme.visualDensity.baseSizeAdjustment.dy)
915+
.clamp(0.0, double.infinity);
911916

912917
return Padding(
913918
padding: const EdgeInsetsDirectional.only(start: 10),

lib/src/controls/form/text_box.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1609,7 +1609,9 @@ class _TextBoxState extends State<TextBox>
16091609
child: Container(
16101610
foregroundDecoration: foregroundDecoration,
16111611
constraints: BoxConstraints(
1612-
minHeight: (32 + themeData.visualDensity.baseSizeAdjustment.dy).clamp(0.0, double.infinity),
1612+
minHeight:
1613+
(32 + themeData.visualDensity.baseSizeAdjustment.dy)
1614+
.clamp(0.0, double.infinity),
16131615
),
16141616
child: _selectionGestureDetectorBuilder
16151617
.buildGestureDetector(

lib/src/controls/navigation/navigation_view/indicators.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,10 @@ class _StickyNavigationIndicatorState
380380

381381
final fluentTheme = FluentTheme.of(context);
382382
final densityAdjustment = fluentTheme.visualDensity.baseSizeAdjustment.dy;
383-
final paneItemMinHeight = (kPaneItemMinHeight + densityAdjustment).clamp(0.0, double.infinity);
383+
final paneItemMinHeight = (kPaneItemMinHeight + densityAdjustment).clamp(
384+
0.0,
385+
double.infinity,
386+
);
384387

385388
return IgnorePointer(
386389
child: Align(

lib/src/controls/navigation/navigation_view/pane_items.dart

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,10 @@ class PaneItem extends NavigationPaneItem {
205205
final theme = NavigationPaneTheme.of(context);
206206
final fluentTheme = FluentTheme.of(context);
207207
final densityAdjustment = fluentTheme.visualDensity.baseSizeAdjustment.dy;
208-
final paneItemMinHeight = (kPaneItemMinHeight + densityAdjustment).clamp(0.0, double.infinity);
208+
final paneItemMinHeight = (kPaneItemMinHeight + densityAdjustment).clamp(
209+
0.0,
210+
double.infinity,
211+
);
209212

210213
final titleText = title?._getProperty<String>() ?? '';
211214
final baseStyle = title?._getProperty<TextStyle>() ?? const TextStyle();
@@ -273,9 +276,7 @@ class PaneItem extends NavigationPaneItem {
273276
case PaneDisplayMode.compact:
274277
return Container(
275278
key: key,
276-
constraints: BoxConstraints(
277-
minHeight: paneItemMinHeight,
278-
),
279+
constraints: BoxConstraints(minHeight: paneItemMinHeight),
279280
alignment: AlignmentDirectional.centerStart,
280281
padding: theme.iconPadding ?? EdgeInsetsDirectional.zero,
281282
child: infoBadge != null
@@ -299,9 +300,7 @@ class PaneItem extends NavigationPaneItem {
299300

300301
return ConstrainedBox(
301302
key: key,
302-
constraints: BoxConstraints(
303-
minHeight: paneItemMinHeight,
304-
),
303+
constraints: BoxConstraints(minHeight: paneItemMinHeight),
305304
child: ClipRect(
306305
child: Row(
307306
children: [
@@ -899,9 +898,10 @@ class __PaneItemExpanderState extends State<_PaneItemExpander>
899898
final displayMode = body.displayMode;
900899
final navigationTheme = NavigationPaneTheme.of(context);
901900

901+
final textDirection = Directionality.of(context);
902902
flyoutController.showFlyout<void>(
903903
placementMode: displayMode == PaneDisplayMode.compact
904-
? FlyoutPlacementMode.rightTop
904+
? FlyoutPlacementMode.rightTop.resolve(textDirection)
905905
: FlyoutPlacementMode.bottomCenter,
906906
forceAvailableSpace: true,
907907
barrierColor: Colors.transparent,

0 commit comments

Comments
 (0)