Skip to content

Instantly share code, notes, and snippets.

@fredgrott
Created December 28, 2025 20:24
Show Gist options
  • Select an option

  • Save fredgrott/37594281916e5a9f047396f8ffdfad55 to your computer and use it in GitHub Desktop.

Select an option

Save fredgrott/37594281916e5a9f047396f8ffdfad55 to your computer and use it in GitHub Desktop.
window height
// Copyright 2025 Fredrick Allan Grott. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// Modified from window_size_classes package by Yuna
// Copyright 2025 under GNU LGPL 3.0
import 'package:flutter/widgets.dart';
import 'package:material_expressive_collection/src/adaptive/breakpoints.dart';
import 'package:meta/meta.dart';
/// Opinionated set of vertical viewport breakpoints.
///
/// [WindowHeight] can be used to adjust the layout when available vertical
/// space is unusually small or large.
///
/// However, since most layouts contain vertically scrolling content, it's rare
/// that layouts need to adjust to available height.
///
/// ```dart
/// final windowHeight = WindowHeight.of(context);
///
/// if (windowHeight == WindowHeight.compact) {
/// // Adapt UI for limited vertical space
/// }
/// ```
///
/// See also:
///
/// * <https://developer.android.com/develop/ui/compose/layouts/adaptive/use-window-size-classes>
/// * [WindowWidth], for categorizing horizontal space.
/// * [FluterView View.of(this).size], which provides the window dimensions.
enum WindowHeight implements Comparable<WindowHeight> {
/// Compact height class.
///
/// Applies to windows with height less than [mediumHeightBreakpoint]
/// (480 logical pixels).
///
/// Common devices:
///
/// - Phones in landscape
///
/// See also:
///
/// * <https://developer.android.com/develop/ui/compose/layouts/adaptive/use-window-size-classes>
compact,
/// Medium height .
///
/// Applies to windows with a height of at least [mediumHeightBreakpoint]
/// (480 logical pixels) and less than [expandedHeightBreakpoint] (900
/// logical pixels).
///
/// Common devices:
///
/// - Tablets in landscape
/// - Phones in portrait
///
/// See also:
///
/// * <https://developer.android.com/develop/ui/compose/layouts/adaptive/use-window-size-classes>
medium,
/// Expanded height .
///
/// Applies to windows with height of [expandedHeightBreakpoint] (900 logical
/// pixels) or more.
///
/// Common devices:
///
/// - Tablets in portrait
///
/// See also:
///
/// * <https://developer.android.com/develop/ui/compose/layouts/adaptive/use-window-size-classes>
expanded;
/// Returns the [WindowHeight] for the current screen height.
///
/// Retrieves the screen height from [MediaQuery] and determines the
/// appropriate [WindowHeight] based on the Android breakpoints.
///
/// The [context] must have a [MediaQuery] ancestor.
///
/// ```dart
/// Widget build(BuildContext context) {
/// final windowHeight = WindowHeight.of(context);
/// // This value can change during the app's lifetime
/// // Adapt your layout based on available vertical space...
/// }
/// ```
@useResult
@pragma('dart2js:tryInline')
@pragma('vm:prefer-inline')
@pragma('wasm:prefer-inline')
static WindowHeight of(BuildContext context) {
// changed to support foldables
return fromHeight(View.of(context).display.size.height);
}
/// Returns the [WindowHeight] for the given [height] value.
///
/// The [height] parameter should be in logical pixels.
/// This method applies breakpoint logic to determine the appropriate
/// height class for the available vertical space.
///
/// ```dart
/// final windowHeight = WindowHeight.fromHeight(600); // Returns medium
/// final windowHeight = WindowHeight.fromHeight(1000); // Returns expanded
/// ```
@useResult
static WindowHeight fromHeight(num height) {
return switch (height) {
>= expandedHeightBreakpoint => WindowHeight.expanded,
>= mediumHeightBreakpoint => WindowHeight.medium,
_ => WindowHeight.compact,
};
}
/// Whether this height class is smaller than [other].
///
/// Returns `true` if this height class is smaller than [other].
/// Returns `false` if this height class is greater than or equal to [other].
bool operator <(WindowHeight other) => index < other.index;
/// Whether this height class is smaller than or equal to [other].
///
/// Returns `true` if this height class is smaller than or equal to [other].
/// Returns `false` if this height class is greater than [other].
bool operator <=(WindowHeight other) => index <= other.index;
/// Whether this height class is greater than [other].
///
/// Returns `true` if this height class is greater than [other].
/// Returns `false` if this height class is smaller than or equal to [other].
bool operator >(WindowHeight other) => index > other.index;
/// Whether this height class is greater than or equal to [other].
///
/// Returns `true` if this height class is greater than or equal to [other].
/// Returns `false` if this height class is smaller than [other].
bool operator >=(WindowHeight other) => index >= other.index;
/// Compares this [WindowHeight] to [other].
///
/// Returns a negative integer if this [WindowHeight] represents a
/// smaller height than [other], zero if they represent the same height class,
/// or a positive integer if this [WindowHeight] represents a larger
/// height than [other].
@override
@pragma('dart2js:tryInline')
@pragma('vm:prefer-inline')
@pragma('wasm:prefer-inline')
int compareTo(WindowHeight other) => index.compareTo(other.index);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment