Closed claviska closed 4 years ago
@claviska I like how ui-library implement the toast ui-library-toast They use a different approach, like dynamically creating the components on run time. Similar way angular material does with cdk-overlay.
ui-libarary toast only show the message, for other features we can implement. I guess they are not be too complex.
its a good starting point.
The trouble with a controller is that you can't compose things neatly.
Alerts can contain arbitrary HTML, for example, so you'd have to expose some kind of html
argument, not just a message string. But what if the alert has something like an "undo" button in it? How would you listen to it if the button were passed as an HTML string?
Or you could go down the road of accepting opinionated arguments such as message
, iconName
, iconURL
, buttons[]
β it quickly gets messy and ultimately limits what you can do. π
So I came up with this the other day. It involves extending the show
method to support a "toast" interface. In this example, queueing would be handled by the component, not a utility.
<sl-alert>
<sl-icon slot="icon" name="info-circle"></sl-icon>
This is an alert!
</sl-alert>
<script>
const alert = document.querySelector('sl-alert');
alert.show({
toast: true,
position: 'top-start',
duration: Infinity
});
</script>
This leaves composition up to the user so they can create the element in their HTML template or in JS with document.createElement()
. They could also create a thin wrapper based on their needs with shortcut methods:
function customAlert(message, duration) {
const alert = document.createElement('sl-alert');
alert.textContent = message;
alert.show({
toast: true,
duration
});
}
Not sure. Still need to think about this some more.
yea it totally make sense, the way you ave mentioned. I like this idea. Even you can do a more research over it by checking the angular material snackebar
I experimented with this approach. Preview here: https://shoelace-97gynyc7a.vercel.app/components/alert?id=toast-notifications
My concerns:
<sl-alert>
can function as an alert and as a toast notification (plus thereβs nothing in the sidebar for discovery).<div>
for the toast stack. To customize it, you have to style .sl-toast-stack
which is a new pattern and I donβt love it.toast
and open
props will move alert around in the DOM, and ultimately it gets removed. This doesn't align with how declarative APIs are expected to work.$.alert(...)
I spent some time looking at other web components and how they're doing it. I haven't found a single example that supports multiple/stackable toast notifications in a declarative way.
I may experiment with an imperative approach, similar to what Lightning is doing. If there's an imperative API that covers 95% of use cases, maybe that's the better approach. Something like:
import { createNotification } from '@shoelace-style/shoelace';
createNotification({
type: 'primary',
closable: true,
duration: 3000,
title: 'Toast',
message: 'This is a toast notification',
iconName: 'info-circle',
iconSrc: null, // for custom icons
});
Then we can expose an advanced property that lets you pass in an <sl-alert>
element should you need to fully customize it:
import { createNotification } from '@shoelace-style/shoelace';
const alert = document.createElement('sl-alert');
alert.type = 'primary';
alert.innerHTML = '...';
createNotification({
element: alert
});
Thoughts?
Another experiment: https://shoelace-7j37ar5bp.vercel.app/components/alert?id=toast-notifications
The docs and the source sums up this approach, but it basically exposes a toast()
method that hoists and shows the notification.
This is my favorite approach thus far, but Iβd still like some feedback on it.
Implemented in e797f2788252d341d81803921d6759116cc7f9dc.
A toast/snackbar component (or utility) that shows an unobtrusive alert.
Please vote for this feature with π or π