just_sonner 0.4.2
just_sonner: ^0.4.2 copied to clipboard
Stacking toasts for Flutter desktop in the spirit of sonner: a deck that fans out on hover, toasts updated in place, promise toasts, no BuildContext.
0.4.2 #
- The deck takes the pointer only where it is drawn (#104). While the pointer held a deck that
could scroll, the deck kept the pointer in the band
offsetkeeps clear at its edge and a margin past the cap, where nothing of it was drawn: a click there did not reach your app, and a pointer moved there kept the deck fanned out with its timers stopped. Both bands are now your app's, before and after a scroll. - A deck with no cap is cut at the far edge's
offset(#104). WithdeckCap: () => null, a deck taller than the window was drawn into the bandoffsetkeeps clear on the far side, as 0.4.0 fixed at the near end (#86). It is now cut there, hard.
0.4.1 #
- The backdrop stays out of the
offsetband before the deck is scrolled too (#101). WithdeckBackdropset and the pointer resting on a deck that can scroll, the backdrop was drawn from the window's edge rather than fromoffset, over the band an app keeps clear for its own title bar, until a scroll cut it there. It is now cut at theoffsetedge whether the deck has scrolled or not, andDeckBackdrop.paddinggives way to it there. Clicks are unchanged. - The example app opens on a showcase (#29): every argument of
showand every part ofSonnerConfigon a control, grouped on one page, beside buttons that show toasts with them. The harness each behaviour was verified in is on a page of its own, behind the app bar.
0.4.0 #
-
Breaking: a toast with no timer is shown with
duration: null, notDuration.zero(#97). A toast shown with adurationis a transient toast and goes when it runs out; one shown withduration: nullstays until the user or your app dismisses it; one shown without adurationtakesconfig.durationas before.Duration.zeronow asserts in debug, onshow,updateandSonnerConfig, where it used to mean "no timer": writeduration: nullinstead.config.durationis aDuration?, set to null withcopyWith(duration: () => null), which makes every toast shown without a duration stay.update(id, duration: null)takes a toast's timer away, andToastContent(duration: null)makes apromiseresult stay. A function that passes a duration on toshownow needs a default: with a plainDuration? duration, every call that leaves it out passes null and shows a toast with no timer. Give itDuration? duration = SonnerConfig.configDuration. Apromise's loading content takes nodurationat all, andToastContent(duration: null)there now asserts as any other duration does. -
Breaking: the zone replaces stowing (#97).
toast.zoneis the layer the deck lives in, your app's to open and close, and it exists with no toast up. Its state is shown, open or hidden:zone.open()fans every toast out with no pointer, the ones beyondvisibleToastsincluded, with the controls past the far end, and pauses nothing. With no toast it draws a card reading "No notifications" (config.zoneEmpty, null for none, or a builder of your own). The last toast leaving does not close it.zone.close()returns to the stateopen()was called from, so a zone opened from hidden hides again — a title-bar notification button needs no other code.zone.hide()takes the deck out of sight with its toasts kept and counting down, asstow()did — but a new toast no longer brings the deck back: it shows the deck as a banner, the older toasts in it, until it has gone and the pointer has left, and the zone stays hidden. An empty zone stays hidden too.zone.reveal()brings it back.zone.heldsays whether the pointer holds the deck, and the controller notifies when it changes, so your app decides what closes the zone.
Removed:
stow(),unstow()andstowed, and the edge handle —stowHandle,DeckStowHandle,DeckStowHandleViewandDeckStowHandleBuilder; the entrance to a hidden zone is your app's own control. Renamed:stowControl→hideControlandstowMotion→hideMotion, withDeckStowControl,DeckStowLook,DeckStowView,DeckStowBuilder,DeckStowMotion,DeckStowMotionLook,DeckStowMotionViewandDeckStowMotionBuilder→DeckHide…; a view'sstowishide, and a motion view'sstowedishidden. The Hide control now also shows on an open zone with no toast, and on a banner it takes the banner down. New:SonnerZone,ZoneState,ZoneEmpty,ZoneEmptyViewandZoneEmptyBuilder, andSonnerConfig.configDurationfrom the entry above. -
Breaking: a drag a toast will not leave on moves it a little on either axis (#87). A toast on a centered deck used not to move at all when dragged sideways, since neither left nor right is a way out there, while a drag down on the same toast moved it a little and sprang back. Every drag the toast will not leave on is now damped that way, whichever axis it takes.
swipeDirections: {}changes meaning with it: it used to take the swipe away, and now lets no swipe dismiss while a drag still moves the toast and springs it back. To take the drag away altogether, make the toast notdismissible. -
A scrolled deck no longer draws over the
offsetband (#86). The deck is now cut at its near end as well as its far one. Scrolling a deck that overflows used to push toasts past the edge's ownoffsetand go on painting them there — over the band an app keeps clear for its own title bar, and off the layer. The near end sits at thatoffset, fades overDeckCap.fadeinward from it, and cuts hard where there is no fade; it does not need adeckCapat all, so a deck taller than the layer is cut there too. An exiting toast and the backdrop are cut with it. Clicks are unchanged: the near cut is paint only.
0.3.1 #
- The fanned-out deck can blur what is behind it (#78).
config.deckBackdropis null by default and draws nothing, so nothing changes until you ask for it. With aDeckBackdropthe deck softens what is behind it as it fans out under the pointer, and fades it back as it collapses:bluris the filter's sigma,dimandcolora cover over it (colornull follows the theme'scolorScheme.scrim),paddinghow far past the deck it reaches, andradiusits corners. A click in that padding still reaches your app — what it draws over claims no pointer the deck did not already claim. It blurs what your app painted, not the desktop behind your window.
0.3.0 #
- Breaking:
offsetis anEdgeInsets(#74). Each screen edge takes its own distance, so a deck can clear a title bar at the top and still sit close to the right edge. Writeoffset: EdgeInsets.all(24)where you wroteoffset: 24. The edges are physical. A centered position ignores left and right. The edge the position names holds the deck off it; the opposite one is where the expanded deck stops. - Nothing is drawn past the deck's cap while it stows (#75). With many toasts and a cap that
fades (the default), pressing Hide drew the oldest toasts past the cap for the first half of a
slideorshrinkstow. The fading cut now keeps them out, as a hard cut already did.
0.2.0 #
- A taller toast behind a shorter front keeps its whole card (#72). It is laid out at the front's height rather than cut to it, so its bottom edge and corners are drawn. Before, only the two side edges of its card peeked out past the front.
- Breaking for a builder: a builder is now laid out below its own height whenever its toast is
behind a shorter front. Wrap what is written on the card in the new
ToastFit, inside the card, or build the look with the newtoastCardBuilder, which takes the card and its content apart and also fades the content bycovered. A builder that does neither reports an overflow in debug, which fails a widget test showing toasts of mixed heights. In release the deck clips it, so nothing shows past the card.
0.1.0 #
First release. Desktop only: Windows, macOS and Linux.
- Toasts from anywhere.
toast.showneeds noBuildContextand returns aToastId.updatechanges a toast field by field;showat the id of a toast on screen replaces its content whole. Either way the toast keeps its place and counts down again.dismissanddismissAlltake toasts away. promise. One toast for the whole of a future: loading, then its result or its error. The future's own value or error goes back to the caller unchanged.- Two mount modes.
toast.attach(navigatorKey)draws the toasts in the root navigator's overlay, above dialogs and pages.SonnerHostwraps the app fromMaterialApp.builder. - The deck. Toasts stack into a deck that draws
visibleToastsof them and fans out, every toast drawn, while the pointer is over it. Six positions; width, gap and offset. - Timers pause while the pointer is over the deck, while a toast is dragged, and while the app is hidden. Toasts beyond the deck's window count down like the rest.
- Swipe to dismiss, in the directions the position names or the ones
swipeDirectionsgives. - A default look that follows the theme, light and dark, with a leading slot, an action slot,
a close button, and a spinner while a toast loads.
dismissiblegoverns every way a user dismisses a toast. - A builder that replaces the whole look, per toast or for every toast, handed a
ToastView: the toast's state, its animation, how much the deck covers it, its time left, anddismiss. - Time left, drawn by the default look as a border, a bar, or a ring, each with settings of
its own (
config.timeLeft). - A cap on the expanded deck (
config.deckCap, 400 px by default), past which the toasts scroll, with a draggable scrollbar beside them (config.scrollbar). - Dismiss all from the deck (
config.dismissAll): a pill or a header, or the app's own control through a builder. - Stow the deck:
stow()puts it out of sight, keeping its toasts, until the next new toast orunstow()brings it back. A control on the deck (config.stowControl), a motion (config.stowMotion) and a handle left at the edge (config.stowHandle), each with built-in looks and a builder. - Changing the config with toasts on screen, which the deck follows in place.