Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ au](https://solidcommunity.au/docs/solidui)

## 0.4.0 Refine and Tune

+ Adds additional layout width checks [0.3.6 20260326 tonypioneer]
+ Add checkbox and new webid widgets to SolidLogin() [0.3.5 20260325 tonypioneer]
+ Add WebID to SetupWizard [0.3.4 20260325 tonypioneer]
+ Login again if webid changed [0.3.3 20260319 tonypioneer]
Expand Down
1 change: 1 addition & 0 deletions lib/solidui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export 'src/widgets/solid_nav_models.dart';

export 'src/widgets/solid_scaffold.dart';
export 'src/widgets/solid_scaffold_controller.dart';
export 'src/widgets/solid_scaffold_helpers.dart' show SolidScaffoldHelpers;
export 'src/widgets/solid_scaffold_models.dart';

export 'src/widgets/solid_status_bar.dart';
Expand Down
15 changes: 10 additions & 5 deletions lib/src/constants/navigation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,21 @@ library;
/// Navigation constants used throughout the application.

class NavigationConstants {
/// The width threshold for determining very narrow screen layout.

static const double veryNarrowScreenThreshold = 600.0;

/// The width threshold for determining narrow/wide screen layout.
///
/// Screens wider than this value will use the navigation rail,
/// while narrower screens will use the navigation drawer.

static const double narrowScreenThreshold = 800.0;

/// The width threshold for determining very narrow screen layout.
/// The width threshold for wide screen layout.

static const double veryNarrowScreenThreshold = 600.0;
static const double wideScreenThreshold = 900.0;

/// The width threshold for very wide screen layout.

static const double veryWideScreenThreshold = 1000.0;

/// Minimum width for the navigation rail.

Expand Down
79 changes: 61 additions & 18 deletions lib/src/constants/ui_window.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,33 +30,78 @@ library;

import 'package:flutter/material.dart';

/// Thresholds for window size.
import 'package:solidui/src/constants/navigation.dart';

/// Responsive layout helpers using [LayoutBuilder] constraints.

class WindowSize {
/// Small width threshold.

static const double smallWidthLimit = 600;
static const double smallWidthLimit =
NavigationConstants.veryNarrowScreenThreshold;

/// Small height threshold.

static const double smallHeightLimit = 600;

/// Boolean describing whether the parent widget is narrow.
/// Derived from the box constraints found by LayoutBuilder().
///
/// Arguments:
/// - [constraints] - The box constraints of the parent widget
/// where LayoutBuilder() was called.
/// Legacy method — equivalent to [isVeryNarrow].

bool isNarrowWindow(BoxConstraints constraints) {
final bool isNarrow;
if (constraints.maxWidth < WindowSize.smallWidthLimit) {
isNarrow = true;
} else {
isNarrow = false;
}
return isVeryNarrow(constraints);
}

/// Whether [constraints] width is below the very narrow threshold.

static bool isVeryNarrow(
BoxConstraints constraints, {
double threshold = NavigationConstants.veryNarrowScreenThreshold,
}) {
return constraints.maxWidth < threshold;
}

return isNarrow;
/// Whether [constraints] width falls in the narrow range, i.e. between
/// [veryNarrowThreshold] (inclusive) and [narrowThreshold] (exclusive).

static bool isNarrow(
BoxConstraints constraints, {
double veryNarrowThreshold = NavigationConstants.veryNarrowScreenThreshold,
double narrowThreshold = NavigationConstants.narrowScreenThreshold,
}) {
return constraints.maxWidth >= veryNarrowThreshold &&
constraints.maxWidth < narrowThreshold;
}

/// Whether [constraints] width falls in the medium range, i.e. between
/// [narrowThreshold] (inclusive) and [wideThreshold] (exclusive).

static bool isMedium(
BoxConstraints constraints, {
double narrowThreshold = NavigationConstants.narrowScreenThreshold,
double wideThreshold = NavigationConstants.wideScreenThreshold,
}) {
return constraints.maxWidth >= narrowThreshold &&
constraints.maxWidth < wideThreshold;
}

/// Whether [constraints] width falls in the wide range, i.e. between
/// [wideThreshold] (inclusive) and [veryWideThreshold] (exclusive).

static bool isWide(
BoxConstraints constraints, {
double wideThreshold = NavigationConstants.wideScreenThreshold,
double veryWideThreshold = NavigationConstants.veryWideScreenThreshold,
}) {
return constraints.maxWidth >= wideThreshold &&
constraints.maxWidth < veryWideThreshold;
}

/// Whether [constraints] width exceeds the very wide threshold.

static bool isVeryWide(
BoxConstraints constraints, {
double threshold = NavigationConstants.veryWideScreenThreshold,
}) {
return constraints.maxWidth >= threshold;
}
}

Expand Down Expand Up @@ -87,9 +132,7 @@ class ListItemSize {

final double cardAspectRatio;

// Derive card aspect ratio (width / height).

if (constraints.maxWidth < WindowSize.smallWidthLimit) {
if (WindowSize.isVeryNarrow(constraints)) {
cardAspectRatio = constraints.maxWidth / compressedItemHeight;
} else {
cardAspectRatio = constraints.maxWidth / uncompressedItemHeight;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ ElevatedButton resCreateFormSubmission(
// Use MediaQuery to determine the screen width and adjust the font size
// accordingly.

final screenWidth = MediaQuery.of(context).size.width;
final screenWidth = MediaQuery.sizeOf(context).width;
final isSmallDevice =
screenWidth < 360; // A threshold for small devices, can be adjusted.

Expand Down
2 changes: 1 addition & 1 deletion lib/src/widgets/build_message_container.dart
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Container buildMsgBox(
// ignore: unused_local_variable
var isRTL = false;

final size = MediaQuery.of(context).size;
final size = MediaQuery.sizeOf(context);
final loc = Localizations.maybeLocaleOf(context);
final localeLanguageCode = loc?.languageCode;

Expand Down
2 changes: 1 addition & 1 deletion lib/src/widgets/shared_resources_table.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Widget buildSharedResourcesTable(
Map<dynamic, dynamic> sharedResMap,
Widget parentWidget,
) {
final cWidth = MediaQuery.of(context).size.width * 0.18;
final cWidth = MediaQuery.sizeOf(context).width * 0.18;
DataColumn buildDataColumn(String title, String tooltip) {
return DataColumn(
label: Expanded(child: Center(child: Text(title))),
Expand Down
4 changes: 2 additions & 2 deletions lib/src/widgets/solid_file_helpers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class SolidFileHelpers {
if (forceWideScreen != null) {
return forceWideScreen;
}
return MediaQuery.of(context).size.width > 800;
return MediaQuery.sizeOf(context).width > 800;
}

/// Gets the effective browser height.
Expand All @@ -54,7 +54,7 @@ class SolidFileHelpers {
if (browserHeight != null) {
return browserHeight;
}
return MediaQuery.of(context).size.height * 0.7;
return MediaQuery.sizeOf(context).height * 0.7;
}

/// Gets the effective upload configuration, either from the provided config
Expand Down
4 changes: 2 additions & 2 deletions lib/src/widgets/solid_login_build_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,12 @@ class SolidLoginBuildHelper {
behavior: HitTestBehavior.deferToChild,
child: SafeArea(
child: DecoratedBox(
decoration: isNarrowScreen(context)
decoration: isNarrowLoginScreen(context)
? loginBoxDecor
: const BoxDecoration(),
child: Row(
children: [
isNarrowScreen(context)
isNarrowLoginScreen(context)
? Container()
: Expanded(
flex: 7,
Expand Down
6 changes: 3 additions & 3 deletions lib/src/widgets/solid_login_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ import 'package:markdown_tooltip/markdown_tooltip.dart';
const int narrowScreenLimit = 1175;
const int veryNarrowScreenLimit = 750;

double screenWidth(BuildContext context) => MediaQuery.of(context).size.width;
double screenWidth(BuildContext context) => MediaQuery.sizeOf(context).width;

bool isNarrowScreen(BuildContext context) =>
bool isNarrowLoginScreen(BuildContext context) =>
screenWidth(context) < narrowScreenLimit;

bool isVeryNarrowScreen(BuildContext context) =>
bool isVeryNarrowLoginScreen(BuildContext context) =>
screenWidth(context) < veryNarrowScreenLimit;

/// Button styles used in the Solid Login widget.
Expand Down
6 changes: 4 additions & 2 deletions lib/src/widgets/solid_login_panel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class SolidLoginPanel {
if (isRequired)
Expanded(
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.5,
width: MediaQuery.sizeOf(context).width * 0.5,
child: infoButton,
),
),
Expand Down Expand Up @@ -178,7 +178,9 @@ class SolidLoginPanel {
required SolidLoginThemeMode currentTheme,
}) {
final loginPanelInset =
(isVeryNarrowScreen(context) || !isNarrowScreen(context)) ? 0.05 : 0.25;
(isVeryNarrowLoginScreen(context) || !isNarrowLoginScreen(context))
? 0.05
: 0.25;

return Container(
margin: EdgeInsets.symmetric(
Expand Down
2 changes: 1 addition & 1 deletion lib/src/widgets/solid_nav_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class SolidNavBar extends StatelessWidget {
child: SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: MediaQuery.of(context).size.height,
minHeight: MediaQuery.sizeOf(context).height,
),
child: IntrinsicHeight(
child: NavigationRail(
Expand Down
2 changes: 1 addition & 1 deletion lib/src/widgets/solid_nav_drawer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ class _SolidNavDrawerState extends State<SolidNavDrawer> {
),
),
child: ListView(
padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
padding: EdgeInsets.only(top: MediaQuery.paddingOf(context).top),
children: <Widget>[
if (widget.userInfo != null)
SolidNavDrawerHeader.build(
Expand Down
2 changes: 1 addition & 1 deletion lib/src/widgets/solid_nav_drawer_header.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class SolidNavDrawerHeader {
return Container(
padding: EdgeInsets.only(
top: NavigationConstants.userHeaderTopPadding +
MediaQuery.of(context).padding.top,
MediaQuery.paddingOf(context).top,
bottom: bottomPadding,
),
decoration: BoxDecoration(color: theme.colorScheme.primaryContainer),
Expand Down
27 changes: 12 additions & 15 deletions lib/src/widgets/solid_scaffold_appbar_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,26 +59,27 @@ class SolidScaffoldAppBarBuilder {
bool showLogout = true,
void Function(BuildContext)? onLogout,
void Function(BuildContext)? onLogin,
required BoxConstraints constraints,
}) {
SolidAppBarActionsManager.initializeIfNeeded(
config,
themeToggle,
hasLogout: showLogout,
);

final isWideScreen = !hideNavRail &&
SolidScaffoldHelpers.isWideScreen(context, narrowScreenThreshold);
final screenWidth = MediaQuery.of(context).size.width;
final layoutWidth = constraints.maxWidth;
final isNarrowScreen = hideNavRail ||
SolidScaffoldHelpers.isNarrowScreen(
constraints,
narrowThreshold: narrowScreenThreshold,
) ||
SolidScaffoldHelpers.isVeryNarrowScreen(constraints);
final theme = Theme.of(context);

// Build action buttons.

List<Widget> actions = [];

// Add version widget if configured and screen is not too narrow.

if (config.versionConfig != null &&
screenWidth >= config.veryNarrowScreenThreshold &&
layoutWidth >= config.veryNarrowScreenThreshold &&
shouldShowVersion) {
actions.add(
SolidScaffoldHelpers.buildVersionWidget(
Expand All @@ -90,11 +91,9 @@ class SolidScaffoldAppBarBuilder {
actions.add(const Gap(8));
}

// Build ordered actions based on preferences.

final orderedActions = SolidAppBarOrderedActionsBuilder.build(
config: config,
screenWidth: screenWidth,
layoutWidth: layoutWidth,
themeToggle: themeToggle,
currentThemeMode: currentThemeMode,
themeToggleCallback: themeToggleCallback,
Expand All @@ -106,12 +105,10 @@ class SolidScaffoldAppBarBuilder {
);
actions.addAll(orderedActions);

// Handle overflow menu if on narrow screen.

SolidAppBarOverflowHandler.handleOverflowMenu(
actions,
config,
screenWidth,
layoutWidth,
themeToggle,
currentThemeMode,
themeToggleCallback,
Expand All @@ -125,7 +122,7 @@ class SolidScaffoldAppBarBuilder {
return AppBar(
title: Text(config.title),
backgroundColor: config.backgroundColor,
automaticallyImplyLeading: !isWideScreen,
automaticallyImplyLeading: isNarrowScreen,
actions: actions.isEmpty ? null : actions,
);
}
Expand Down
Loading
Loading