From 0b900d348002dc29ca0f754e343b35f3fd30c227 Mon Sep 17 00:00:00 2001 From: Marc Rejohn Castillano Date: Mon, 23 Feb 2026 18:55:56 +0800 Subject: [PATCH] Fixed horizontal scroll --- lib/widgets/tasq_adaptive_list.dart | 59 +++++++++++++++++++---------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/lib/widgets/tasq_adaptive_list.dart b/lib/widgets/tasq_adaptive_list.dart index cc7f5d3a..957186e4 100644 --- a/lib/widgets/tasq_adaptive_list.dart +++ b/lib/widgets/tasq_adaptive_list.dart @@ -230,7 +230,18 @@ class TasQAdaptiveList extends StatelessWidget { onRowTap: onRowTap, ); - final contentWidth = constraints.maxWidth * 0.8; + // Use progressively smaller fractions of the viewport on larger screens + // so that content doesn't stretch too widely, but also consume as much + // width as possible when the display is more modest. + double contentFactor; + if (constraints.maxWidth < 1200) { + contentFactor = 0.95; // not-so-wide monitors + } else if (constraints.maxWidth < 1800) { + contentFactor = 0.85; // wide monitors + } else { + contentFactor = 0.75; // ultra-wide monitors + } + final contentWidth = constraints.maxWidth * contentFactor; final tableWidth = math.max( contentWidth, (columns.length + (rowActions == null ? 0 : 1)) * 140.0, @@ -240,25 +251,34 @@ class TasQAdaptiveList extends StatelessWidget { math.max(1, items.length), ); - final tableWidget = SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: SizedBox( - width: tableWidth, - child: PaginatedDataTable( - header: tableHeader, - rowsPerPage: effectiveRowsPerPage, - columnSpacing: 20, - horizontalMargin: 16, - showCheckboxColumn: false, - headingRowColor: WidgetStateProperty.resolveWith( - (states) => Theme.of(context).colorScheme.surfaceContainer, + // wrap horizontal scroll with a visible scrollbar on desktop. the + // ScrollController is shared so the scrollbar has something to observe. + final horizontalController = ScrollController(); + final tableWidget = Scrollbar( + controller: horizontalController, + thumbVisibility: true, + trackVisibility: true, + child: SingleChildScrollView( + controller: horizontalController, + scrollDirection: Axis.horizontal, + child: SizedBox( + width: tableWidth, + child: PaginatedDataTable( + header: tableHeader, + rowsPerPage: effectiveRowsPerPage, + columnSpacing: 20, + horizontalMargin: 16, + showCheckboxColumn: false, + headingRowColor: WidgetStateProperty.resolveWith( + (states) => Theme.of(context).colorScheme.surfaceContainer, + ), + columns: [ + for (final column in columns) + DataColumn(label: Text(column.header)), + if (rowActions != null) const DataColumn(label: Text('Actions')), + ], + source: dataSource, ), - columns: [ - for (final column in columns) - DataColumn(label: Text(column.header)), - if (rowActions != null) const DataColumn(label: Text('Actions')), - ], - source: dataSource, ), ), ); @@ -277,6 +297,7 @@ class TasQAdaptiveList extends StatelessWidget { primary: true, child: Center( child: SizedBox( + key: const Key('adaptive_list_content'), width: contentWidth, child: Column( mainAxisSize: MainAxisSize.min,