emilkowalski / sonner

An opinionated toast component for React.
https://sonner.emilkowal.ski
MIT License
8.7k stars 277 forks source link

Make swipe to dismiss discoverable #460

Open volkyeth opened 4 months ago

volkyeth commented 4 months ago

I understand that Sonner intentionally restricts swipe-to-dismiss to the same direction the toast came from, as described in Issue #407 and Issue #274. The limitation to down-only dismissing makes the action difficult to discover, as highlighted in Issue #141, and likely also motivated the aforementioned issues.

I initially thought there was no swipe-to-dismiss feature, and was confused by its mention in the documentation because I was only trying to swipe to the sides. It was not intuitive for me to try swiping down, and it’s an uncomfortable gesture, especially since the toasts are close to the bottom edge, requiring an awkward thumb movement for single-handed use.

Therefore, I respectfully request you to reconsider adding left/right swipe to dismiss. This is an important caveat in an otherwise amazing library. I apologize if this turns out to be unworthy of your time, but I genuinely believe in the merits of this suggestion.

The Case for Left/Right Dismiss

I understand the main motivation for the current implementation is spatial consistency. However, I disagree that swiping left/right to dismiss violates this consistency.

Quoting the Designing Fluid Interfaces presentation, which I believe underpins this decision:

So, if something disappears one way, we expect it to emerge from where it came, right? If I walked off this stage this way and then emerged that way, you'd be amazed because that's impossible. We wanted to play into this consistent sense of space. So, if something is going out of view and coming back into view, it should do so in symmetric paths.

This principle would be applicable if the same toast were to reappear. However, toasts are ephemeral notifications; dismissing them to the sides does not break spatial expectations. In fact, it can emphasize the different identities of toasts, even with identical content.

There seems to be a misconception that toasts are stable UI elements like a dock or sidebar, hence requiring consistent entry and exit paths. The more fitting metaphor for notifications is the "stack of cards":

This card metaphor is extensively used in mainstream touch interfaces (e.g., notifications on Android/iOS). Sonner aligns with this metaphor since toasts stack, are fannable, and can be swiped away.

Alternatives to Improve Discoverability

If the above argument doesn’t persuade you, I still believe the issue of discoverability needs addressing. Here are some alternative solutions:

Dropzone Visual Affordance

Adding a dropzone visual affordance when a finger is held over a toast could give users a clear target for dismissing. This could be a faint glow/shadow on the edge where dismissed toasts are directed.

Lifting the Toast on Touch

Another option is to lift the toast from the page by increasing the vertical offset of its shadow when touched. Currently, there's no indication that a toast supports gestures when a user holds their finger over it. This visual affordance could nudge users to try other gestures, even if it doesn't explicitly indicate the need to swipe down.

emilkowalski commented 4 months ago

Great metaphor. Will implement this in the upcoming days.

rashmod commented 3 months ago

I reviewed the previous discussions and noticed that adding a horizontal swipe to dismiss the toast was initially not planned. However, based on your recent response, I see that you are reconsidering this feature. Please provide an update on whether this feature will be supported in the future. @emilkowalski

mattrossman commented 1 month ago

Another argument for supporting horizontal swipe-to-dismiss is precedent; notifications are dismissed horizontally on MacOS and Android. I only see the vertical dismiss pattern used for notifications on iOS. As an Android and Mac user, it's confusing to see something that resembles a system notification but isn't dismissed the same way. I assume this is why the user in #141 was confused.