bouncy_button 2.1.2
bouncy_button: ^2.1.2 copied to clipboard
A customizable 3D push button with async loading states, springs, button groups, and full accessibility, plus a bouncy press effect for any widget.
2.1.2 - 2026-11-02 #
- The Example tab on pub.dev now shows a one-screen tour of the main features, instead of the demo app's launcher. No code changes.
2.1.1 - 2026-11-02 #
- Rewrote the README: each feature is now explained in plain words with a short example, and the option tables moved to a reference section. No code changes.
2.1.0 - 2026-11-02 #
Added #
cooldownonBouncyButtonandBouncyPressable, which ignores presses for a while after the button is used, so a quick double tap doesn't run an action twice. ForonPressedAsync, it starts once the button is ready again, and errors count too.BouncyAsyncBuilder, which adds double-tap protection and loading, success, and error states to any button, including Material and Cupertino ones. It needs no Material code and is also exported frompackage:bouncy_button/pressable.dart.BouncyButtonController, to press or reset a button from code and follow its status.BouncyExclusiveScope.lockDuringLoading, which lets only one async action below it run at a time.BouncyButtonFeedback.minLoadingDuration, so a very fast action doesn't flash the spinner.BouncyButtonFeedback.loadingText, shown beside the spinner and read by screen readers.BouncyButton.tooltip.- A destructive tone:
BouncyButtonStyle.tonewithBouncyButtonTone.destructive, and aBouncyButtonStyle.destructivepreset. It uses the theme's error colors with every fill. BouncyButtonStyle.minTapTarget, which enlarges the tap area of a small button without changing how it looks.BouncyHapticFeedbackTypeandBouncyGradientExtension, prefixed names that can't clash with other packages.
Deprecated #
HapticFeedbackType, renamedBouncyHapticFeedbackType. The old name still works.GradientExtension, renamedBouncyGradientExtension. Implicit calls such asgradient.scaleLightness(0.5)are unaffected.
Changed #
BouncyButtonStatusmoved to the library's enums, so it is available without Material. Imports ofpackage:bouncy_button/bouncy_button.dartare unaffected.
2.0.0 - 2026-11-02 #
Breaking changes #
- Width: a button with no
widthnow sizes to its child, as the docs always said, instead of filling all available space. To keep a full-width button, setwidth: double.infinityor place it where the parent forces a width, such as insideExpanded. - Height:
BouncyButtonStyle.heightis now a minimum, so the face grows instead of clipping large text. Circular buttons stay exactly this tall. - Dragging: dragging a finger across the button and releasing no longer counts as a press. Press and release is now handled the same way as Material buttons: moving away cancels the press.
- Colors: with no colors set, the face now uses
colorScheme.primaryinstead ofprimaryColor, and text and icons default to a contrasting color. A color set directly on the child still wins. - Long press only: a button with
onLongPressbut noonPressedis now enabled, so it looks enabled and can take focus. It used to render as disabled and ignore the long press. - Nullable fields:
BouncyButton.style,animation, andinteractionare now nullable, because null means "use the theme". BouncyButtonStyle.flatis 46 tall instead of 44, so it reaches the 48px minimum tap target with its elevation.BouncyButtonAnimation.bouncyhas new values and now springs past its resting position on release.bounceanimations now usescaleAmountand stay scaled while held. They used to return to full size during a long hold.hslColornow also paints the face whenbackgroundColoris null.- Requires Flutter 3.27 or later. The old
>=3.10.0constraint was never accurate, because Dart^3.6.0already required it.
Fixed #
- Quick taps now show the full press. Taps shorter than about 100ms used to show no movement at all.
- The button no longer throws inside a
Rowor other parent with unbounded width. BouncyButtonThemenow works. It was documented but never read by the widget.- Enter and Space now activate a focused button, and a focus ring shows during keyboard navigation.
- Disabled buttons can no longer take focus.
- Screen readers now always announce a button, and no longer offer scroll actions on it.
semanticLabelreplaces the child's label instead of being read alongside it. - The system "reduce motion" setting is now respected.
enableSplash: trueno longer removes the press animation and haptics from quick taps.enableSplash: trueno longer throws with aBorderRadiusDirectional.- Disabling a button while it is held no longer throws or leaves it stuck down.
- The button now stays down for the whole of a long press.
- Disabled gradients are now darkened as intended rather than made see-through, and the depth layer matches them.
- Changing
curveat runtime now takes effect. - The default colors no longer make the button invisible on dark themes.
- Animation frames no longer rebuild the button's contents or
builder. pub getis far smaller: the package archive no longer includes the demo GIFs.
Added #
BouncyPressable, which adds the press effect to any widget. It needs no Material code, and is also available on its own frompackage:bouncy_button/pressable.dart.- Nested presses: pressing a button or pressable inside another leaves the outer one still.
BouncyExclusiveScope, which allows only one press at a time below it.BouncyButton.onPressedAsync, which shows a loading state until the returned future completes, then success or an error. The button ignores presses meanwhile, so a form or payment can't be sent twice. Errors go toonError, or toFlutterError.reportError, and are never silently dropped.BouncyButton.isLoading, for loading managed outside the button.BouncyButtonFeedbackto customize loading, success, and error, including the labels screen readers announce. Set it app-wide withBouncyButtonTheme.defaultFeedback.BouncyButton.leading,trailing, andgap, for icons beside the label.BouncyButtonStyle.fillwithBouncyButtonFill.filled,tonal,outlined, andghost, plus matchingtonal,outlined, andghostpresets. Text meets the 4.5:1 contrast minimum in light and dark themes.BouncyButtonStyle.fromSizewithBouncyButtonSize.small,medium, andlarge, which scale height, depth, padding, and text together. Every size is at least 48 pixels tall.BouncyButtonStyle.textStyleandiconSize.BouncyButtonStyle.simple, for quick setup from a color and size, and theshadowLightandshadowDarkconstants.BouncyButtonColors.darkenandlighten.BouncyButtonScope, which themes buttons without the MaterialTheme, for apps usingpackage:material_ui.BouncyButtonThemevalue equality.BouncyPressSpringandBouncyButtonAnimation.spring, for spring physics. Pressing again mid-release reverses smoothly from wherever the button is, keeping its speed. Includessnappy,bouncy, andgentlesprings and aBouncyButtonAnimation.springypreset. Also onBouncyPressable.spring.- Hover lift: with a mouse, the face rises slightly while hovered. Set the height with
BouncyButtonInteraction.hoverLift, or 0 to turn it off. Reduced motion turns it off. BouncyButtonStyle.pressedBorderRadius, which morphs the corners as the button is pressed, such as from a pill or circle to a rounded square.BouncyButtonGroupandBouncyButtonSegment, a row of connected buttons for choosing one option or several. Only the outer corners are rounded, on the correct sides in right-to-left layouts, and screen readers announce which segments are selected.BouncyButtonFill.glassandBouncyButtonStyle.glass, a translucent, blurred face with no depth. It turns solid when the system high contrast setting is on.- Press sounds:
BouncyButtonInteraction.enableSoundplays the system click where the platform has one, andonPressSoundplays your own. Also onBouncyPressable. BouncyButton.tertiary, usingBouncyButtonTheme.tertiaryStyle.BouncyButton.onTapDown,onTapUp,onTapCancel, andhitTestBehavior.BouncyButtonStyle.foregroundColor.BouncyButtonAnimation.reverseDurationandreverseCurve.BouncyButtonInteraction.hoverColorandfocusColor.- Value equality for
BouncyButtonStyle,BouncyButtonAnimation, andBouncyButtonInteraction. GradientExtension.scaleLightness.
Deprecated #
GradientExtension.scale.gradient.scale()always called Flutter's ownGradient.scale, so this method never ran without explicit extension syntax. UsescaleLightness.
1.0.4 - 2025-08-15 #
- Improved documentation
1.0.3 - 2025-08-15 #
- Updated Readme file with png and gif
1.0.2 - 2025-08-15 #
- Minor changes in example app
1.0.1 - 2025-08-15 #
- Added Git Repository Info
1.0.0 - 2025-08-15 #
- Initial release
- 3D depth press effect with customizable elevation
- Multiple animation types (depth, scale, rotation, bounce, fade, slide)
- Extensive styling options with gradients and shadows
- Haptic feedback support
- Theme integration
- Predefined button styles (primary, secondary, flat, pill, circle)
- Color manipulation utilities
- Full accessibility support
- Comprehensive documentation and examples
