PackageTrack
Sign in Get early access

assorted_layout_widgets

Widgets SideBySide, RowProportional, AnimatedBetween, Box, Pad, Delayed, WrapSuper, OtpCodeVerificationField, ButtonBarSuper, NormalizedOverflowBox, showDialogSuper and much more.

12.12.1 66K downloads/mo #1308 most downloaded on pub.dev marcglasberg/assorted_layout_widgets

What this package is like to depend on

Last release 17 days ago

06 Aug 2026

Ships unpredictably

gaps range from 9 days to 1.1 years

Some releases are documented

notes for 66 of 127 stable releases

Nothing withdrawn

no release was ever pulled

7 years old

131 releases · first in 2019

21 releases in the last 12 months

see the full history below

Release timeline

131 releases · Nov 2019 to Aug 2026
2020 2021 2022 2023 2024 2025 2026
Release Pre-release

Releases

latest 60 of 131
  1. 12.12.1 06 Aug 2026
    Release notes
    • The new SquircleBorder class is similar to Flutter's ContinuousRectangleBorder, but it allows more configuration options. It defines a rounded-rectangle shape (like a "squircle") where two things are chosen independently: how big the corners are, and how the corner curve looks.

    Open source →
  2. 12.12.0 06 Aug 2026

    Nothing published for this version

  3. 12.11.0 04 Aug 2026
    Release notes
    • New Keyboard parameter closeOnTapOnlyIfKeyboardIsOpen (default false). When true, the close-on-tap behavior (iOsCloseOnTap / androidCloseOnTap) acts only when the system keyboard is actually open: while it's closed, tapping an empty area of the screen does nothing.
    Open source →
  4. 12.10.0 29 Jul 2026
    Release notes
    • New TimeBuilder.each constructor, which rebuilds once for each given interval of time: TimeBuilder.each(interval: const Duration(seconds: 5), builder: ...) rebuilds each 5 seconds. The ticks are aligned to the clock and never drift, so a 5 second interval ticks when the clock reaches the seconds 0, 5, 10, 15 etc. The optional numberOfTicks parameter stops the rebuilds after that number of ticks.
    Open source →
  5. 12.8.0 27 Jul 2026
    Release notes
    • New RowProportional widget, which arranges its children horizontally, dividing all the available horizontal space between them, proportionally to their preferred (natural, intrinsic) widths. Children are forced to their calculated widths, so the row never overflows: with extra space the children grow, and with less space they shrink, always keeping their relative proportions. Wrapping a child in an Expanded multiplies its preferred width by the flex, while a Flexible also allows the child to be smaller than its calculated width. If one or more children are Spacers, there is no scaling anymore: the other children get their preferred widths, and the leftover space is divided between the spacers.

    • New FixedWidth widget, to be used as a direct child of RowProportional, gives a child an immutable width that never scales and does not participate in the proportional distribution of space. Use FixedWidth(width: 8) with no child for a fixed 8 pixel gap, FixedWidth(width: 50, child: ...) to pin a child at exactly 50 pixels, or FixedWidth(child: ...) with no width to fix a child at its own preferred width. If the fixed widths alone exceed the available space, they shrink proportionally to each other, so the row still never overflows.

    Open source →
  6. 12.7.1 27 Jul 2026
    Release notes
    • AnimatedBetween now reports proper intrinsic dimensions, so it can be used inside parents that measure children by intrinsics (IntrinsicWidth, IntrinsicHeight, RowSuper, etc.). At rest it reports its child's intrinsics; mid-transition it reports the current animated box size, so intrinsic-measuring parents animate along. Visual behavior is unchanged.
    Open source →
  7. 12.7.0 24 Jul 2026
    Release notes
    • ThousandsSeparatorTextInputFormatter now accepts an allowedIntegerDigits parameter that limits the integer part to the given number of digits, just like allowedDecimals limits the fractional part. Leading zeros don't count toward the limit, since they are stripped anyway.
    Open source →
  8. 12.6.2 06 Jun 2026
    Release notes
    • New OtpCodeVerificationField widget for one-time-password / verification flows: a row of digit boxes that auto-submits when the last character is entered, with built-in handling for wrong-code, verification-failure, and expiry states, plus an optional countdown timer. Accepted characters are configurable via codeType, codeLetterSet, codeLetterCasing, and customSet, and almost everything visual can be customized.

    • New Email class for email-address handling: isValid() validates an address (with optional top-level-domain and international-character support), sanitize() strips obviously invalid characters, and tryFix() attempts to repair an invalid address into a valid one. The matching EmailTextInputFormatter uses sanitize() to strip invalid characters as the user types.

    • New CapitalizationTextInputFormatter capitalizes text as the user types, with options for uppercase, lowercase, first-letter, or English title case.

    • New NumbersTextInputFormatter allows only numeric input — integer, or decimal with locale-aware, dot, or comma separators.

    • New AllowedCharsTextInputFormatter allows only the characters that match a given regular expression, filtering out everything else.

    • New NoSpacesTextInputFormatter prevents the user from typing any whitespace, removing spaces, tabs, and newlines from the input.

    • New AlwaysAtTheEndTextInputFormatter forces the cursor to always stay at the end of the text being typed.

    • New StringDotLengthLimiterTextInputFormatter limits text by Dart's String.length (instead of grapheme clusters), useful when matching server, database, or file-format limits.

    Open source →
  9. 12.6.1 01 May 2026

    Nothing published for this version

  10. 12.6.0 01 May 2026

    Nothing published for this version

  11. 12.5.1 26 Apr 2026
    Release notes
    • Widget KeyboardDismiss is now deprecated.

      To fix the deprecation warning, replace:

      KeyboardDismiss(child: ...)
      

      with:

      Keyboard(
        iOsCloseOnTap: true, 
        iOsCloseOnSwipe: true, 
        iOsRemoveFocusOnTap: true, 
        child: ...
      )
      
    • The new Keyboard widget allows you to show different content depending on whether the system keyboard is open or closed. If also controls the behavior of the system keyboard on both iOS and Android, including auto-dismissing the keyboard when the user taps outside it or swipes down from just above the keyboard edge.

      Place the Keyboard widget near the top of the widget tree, where it has the same size as the screen, for example, in MaterialApp.builder, above any Scaffold. For example:

      MaterialApp(
        builder: (BuildContext context, Widget? child) => 
          Keyboard(     
            iOsCloseOnTap: true,
            iOsCloseOnSwipe: true,
            iOsRemoveFocusOnTap: true,
            child: ...,
          );
      

      Here are the constructor parameters:

      • iOsCloseOnTap closes the keyboard when the user taps an empty area of the screen, on the iOS.
      • iOsCloseOnSwipe closes the keyboard when the user swipes down from just above the keyboard edge, on the iOS.
      • iOsRemoveFocusOnTap controls whether focus is also removed from any focused element when the keyboard is dismissed by a tap, on the iOS.
      • iOsRemoveFocusOnSwipe controls whether focus is also removed from any focused element when the keyboard is dismissed by a swipe, on the iOS.
      • androidCloseOnTap closes the keyboard when the user taps an empty area of the screen, on the Android.
      • androidCloseOnSwipe closes the keyboard when the user swipes down from just above the keyboard edge, on the Android.
      • androidRemoveFocusOnTap controls whether focus is also removed from any focused element when the keyboard is dismissed by a tap, on the Android.
      • androidRemoveFocusOnSwipe controls whether focus is also removed from any focused element when the keyboard is dismissed by a swipe, on the Android.

      The default is false for all the above parameters.

      Recommendation

      On the iOS, it's common for the keyboard to auto-dismiss when the user taps outside it or swipes down from just above the keyboard edge. Usually, when the keyboard is dismissed by a tap, the focused element also loses focus, but when it's dismissed by a swipe, the focused element retains focus (and may re-open the keyboard if it's tapped).

      On the Android, the default is that the keyboard only closes when the user taps the back button or executes the back gesture.

      For these reasons, the recommended configuration is:

      Keyboard(
        iOsCloseOnTap: true,
        iOsCloseOnSwipe: true,
        iOsRemoveFocusOnTap: true,
        child: ...
      );
      
    • Keyboard.isOpen(context) can be used to check whether the keyboard is currently open or not. Example usage: bool isKeyboardOpen = Keyboard.isOpen(context);.

    • Use Keyboard.open() and Keyboard.close() to programmatically open and close the system keyboard.

    • The new KeyboardSwitch widget renders different content depending on whether the system keyboard is open or closed. There are two ways to use it:

      1. The default constructor takes optional open and closed widgets. The open widget is shown when the keyboard is open, and the closed widget when it is closed. Both are optional, and a missing slot renders nothing. Example usage:

        KeyboardSwitch(
           open: Text('Keyboard is open'),
           closed: Text('Keyboard is closed'),
        )
        
      2. The KeyboardSwitch.builder constructor takes a builder callback that receives the current isOpen state, so you can build any widget you want based on it. Example usage:

        KeyboardSwitch.builder(
           (context, isOpen) => Icon(isOpen ? Icons.keyboard : Icons.keyboard_hide),
        )
        

      Note KeyboardSwitch only works if you add a Keyboard widget ancestor. An error will be thrown if you try to use it without a Keyboard ancestor.

    Open source →
  12. 12.5.0 26 Apr 2026

    Nothing published for this version

  13. 12.4.2 17 Apr 2026
    Release notes
    • Added AnimatedBetween widget, which animates smoothly between two children, cross-fading their content while resizing the enclosing box. The old and new children can differ in both width and height, and their sizes don't need to be known in advance. The convenience constructor AnimatedBetween.showHide animates a single widget in and out.
    Open source →
  14. 12.4.1 17 Apr 2026

    Nothing published for this version

  15. 12.4.0 17 Apr 2026

    Nothing published for this version

  16. 12.3.1 02 Apr 2026
    Release notes
    • Added ThousandsSeparatorTextInputFormatter, a formatter for your text-field that formats numeric input with thousands separators as the user types, while preserving the caret position. It accepts integers and decimals.

    • Added KeepTallest widget, which tracks its child's height and never visually shrinks below the tallest height observed so far. Useful for preventing layout jumps when switching between children of different heights (e.g. tab content inside scrollables). Optionally supports animated shrinking back to the child's natural height, with configurable delay, duration, curve, and minimum shrink threshold.

    Open source →
  17. 12.3.0 30 Mar 2026

    Nothing published for this version

  18. 12.2.0 30 Mar 2026

    Nothing published for this version

  19. 12.1.1 30 Mar 2026

    Nothing published for this version

  20. 12.1.0 30 Mar 2026

    Nothing published for this version

  21. 12.0.0 04 Mar 2026
    Release notes
    • Bumped environment:

      • sdk: '>=3.9.2 <4.0.0'
      • flutter: ">=3.35.6"
    • Fixed Button visual bug: When delay is true and the user taps quickly (before the delay timer fires), the visual press feedback now still shows briefly using minVisualTapDuration, instead of being skipped entirely.

    Open source →
  22. 11.0.0 24 Jan 2025
    Release notes
    • Breaking change: The signature of the builders of TimeBuilder have been changed. They all now use named parameters, and also get a new initialTime parameter that was not present before. Migration should be straightforward, Refer to the README for more information.
    Open source →
  23. 11.0.0-dev.1 24 Jan 2025 pre-release

    Nothing published for this version

  24. 10.7.0 23 Jan 2025
    Release notes
    • The ScrollShadow widget adds a shadow at the top and/or bottom, to scrollables like SingleChildScrollView or ListView etc., when the content doesn't fit the scrollable's viewport. As the shadow appears only if there is content outside the viewable area, this gives the user an indication if there is more content to be seen or not.
    Open source →
  25. 10.6.1 23 Jan 2025
    Release notes
    • The DetectScroll widget can detect if the content of a Scrollable is larger than the Scrollable itself, which means that the content can be scrolled, and that a scrollbar is likely visible. It can also tell you the probable width of that scrollbar.

      This is useful for positioning widgets relative to the scrollbar, so that the scrollbar doesn't overlap them. This can be important when the scrollbar is permanently visible, usually on the Web and desktop.

      Note that DetectScroll will only detect the scrolling of its closest scrollable descendant (a scrollable is a SingleChildScrollView, ListView, GridView etc.). Usually, you'd wrap the scrollable you care about directly with a DetectScroll. For example:

      
      

    DetectScroll( child: SingleChildScrollView( child: Column( ... ... );

    
    To get the current scroll state and the scrollbar width, descendants can call:
    
    

    bool canScroll = DetectScroll.of(context).canScroll; double scrollbarWidth = DetectScroll.of(context).scrollbarWidth;

    
    For example, suppose you want to add a help button to the top-right corner of a
    scrollable, and account for the scrollbar width only if it's visible:
    
    

    bool canScroll = DetectScroll.of(context).canScroll; double scrollbarWidth = DetectScroll.of(context).scrollbarWidth;

    return Stack( children: [ child, Positioned( right: canScroll ? scrollbarWidth : 0, top: 0, child: HelpButton(), ), ], );

    
    Another alternative is using the optional `onChange` callback of the `DetectScroll`:
    
    

    DetectScroll( onChange: ({ required bool canScroll, required double scrollbarWidth, }) { // Do something. } child: ... ),

    Open source →
  26. 10.6.0 20 Jan 2025

    Nothing published for this version

  27. 10.5.0 17 Jan 2025
    Release notes
    • The SideBySide widget now has a mainAxisSize property the determines whether it will occupy the full available width (MainAxisSize.max) or only as much as it needs (MainAxisSize.min).
    Open source →
  28. 10.4.4 10 Jan 2025

    Nothing published for this version

  29. 10.4.3 10 Jan 2025

    Nothing published for this version

  30. 10.4.2 10 Jan 2025

    Nothing published for this version

  31. 10.4.1 09 Jan 2025

    Nothing published for this version

  32. 10.4.0 09 Jan 2025

    Nothing published for this version

  33. 10.3.0 09 Jan 2025
    Release notes
    • CircleButton now accepts an optional custom builder function to modify the button's child widget. This can be used to animate the button when the button is tapped, or when the mouse is over it. For example:

      
      

    CircleButton( icon: Icon(Icons.shopping_cart),
    builder: ({ required bool isHover, required bool isPressed, required Widget child, }) => AnimatedScale( scale: isPressed ? 0.85 : 1.0, duration: const Duration(milliseconds: 50), child: child, ), );

    
    Try running
    the [example](https://github.com/marcglasberg/assorted_layout_widgets/blob/master/example/lib/main_button_and_circle_button.dart).
    Open source →
  34. 10.2.4 06 Jan 2025
    Release notes
    • SideBySide widget now allows for any number of children, not just two. Example:

      
      

    SideBySide( children: [ Text("Hello!", textWidthBasis: TextWidthBasis.longestLine), Text("How are you?", textWidthBasis: TextWidthBasis.longestLine), Text("I'm good, thank you.", textWidthBasis: TextWidthBasis.longestLine), ], gaps: [8.0, 12.0], );

    
    The `SideBySide` widget achieves layouts that are not possible with `Row` or `RowSuper`
    widgets. Read the documentation for more information.
    
    **Deprecated usage:** The `startChild` and `endChild` parameters are deprecated.
    Use the `children` parameter instead. The `innerDistance` parameter is also deprecated.
    Use the `gaps` parameter instead.
    
    For example, this deprecated code:
    
    

    return SideBySide( startChild: Text("Hello!", textWidthBasis: TextWidthBasis.longestLine), endChild: Text("How are you?", textWidthBasis: TextWidthBasis.longestLine), innerDistance: 8.0, );

    
    Should be replaced with:
    
    

    return SideBySide( children: [ Text("Hello!", textWidthBasis: TextWidthBasis.longestLine), Text("How are you?", textWidthBasis: TextWidthBasis.longestLine), ], gaps: [8.0], );

    Open source →
  35. 10.2.3 06 Jan 2025

    Nothing published for this version

  36. 10.2.2 06 Jan 2025

    Nothing published for this version

  37. 10.2.1 06 Jan 2025

    Nothing published for this version

  38. 10.2.0 05 Jan 2025

    Nothing published for this version

  39. 10.1.2 02 Jan 2025
    Release notes
    • The Box widget can now have a decoration, as well as a decorationPosition. Previously, if a Container had a decoration you could not replace it with a Box, but now you can. Note the Box is a little more flexible than the Container when you define a color and a BoxDecoration or a ShapeDecoration at the same time, as the Box will only throw an error if the color is defined twice.

    • You can use Box.gap() to create a small gap between widgets:

      
      

    Column( children: [ Text('A'), const Box.gap(8), // 8.0 pixel gap Text('B'), ]);

    Open source →
  40. 10.1.1 01 Jan 2025

    Nothing published for this version

  41. 10.1.0 27 Dec 2024

    Nothing published for this version

  42. 10.0.4 05 Nov 2024
    Release notes
    • Fixed GestureDetector ordering issue for RowSuper and ColumnSuper when the invert param is true.
    Open source →
  43. 10.0.3 30 Oct 2024
    Release notes
    • Removed KeyboardDismiss dependency on dart:io to make it compatible with platform web.

    • Now CircleButton can specify hoverColor (default is no color), and cursor (the default is SystemMouseCursors.click, but you can pass null to set it as MouseCursor.defer).

    Open source →
  44. 10.0.2 29 Oct 2024

    Nothing published for this version

  45. 10.0.1 29 Oct 2024

    Nothing published for this version

  46. 10.0.0 29 Oct 2024

    Nothing published for this version

  47. 9.1.0-dev.1 03 Oct 2024 pre-release

    Nothing published for this version

  48. 9.0.2 20 Jun 2024
    Release notes
    • Added Pad.addValues and Pad.subtractValues.
    Open source →
  49. 9.0.1 24 Jan 2024
    Release notes
    • Flutter 3.16.0 compatible.
    Open source →
  50. 9.0.0 17 Nov 2023

    Nothing published for this version

  51. 8.0.5 08 Oct 2023
    Release notes
    • const WrapSuper.
    Open source →
  52. 8.0.4 01 Jun 2023
    Release notes
    • Removed deprecated TextOneLineEllipsisWithFade widget. Please use TextOneLine instead.
    Open source →
  53. 8.0.3 01 Jun 2023

    Nothing published for this version

  54. 8.0.2 01 Jun 2023

    Nothing published for this version

  55. 8.0.1 01 Jun 2023

    Nothing published for this version

  56. 8.0.0 17 Mar 2023

    Nothing published for this version

  57. 7.0.1 17 Mar 2023
    Release notes
    • Fixed letter-spacing for TextOneLine, whe the style is defined inline.
    Open source →
  58. 7.0.0 30 Aug 2022
    Release notes
    • Flutter 3.3.0 (Dart 2.18.0).

    • TextOneLineEllipsisWithFade deprecated. Please use TextOneLine instead.

    Open source →
  59. 6.1.1 20 Jun 2022
    Release notes
    • KeyboardDismiss.
    Open source →
  60. 6.1.0 20 Jun 2022

    Nothing published for this version

Every package, every release, already written down.

The archive is open and free. Watching your own project is what we are building next.

Browse the archive