components icon indicating copy to clipboard operation
components copied to clipboard

Component request: Banner

Open thw0rted opened this issue 6 years ago • 12 comments

Bug, feature request, or proposal:

Feature request

What is the use-case or motivation for changing an existing behavior?

Material spec has been updated to add a Banner component, and I don't think anything in the current library fits the use cases laid out there. It's pretty similar mechanically to a Snackbar but movement is handled differently.

thw0rted avatar May 22 '18 14:05 thw0rted

Hello, any inputs on this feature dev ? We will need it as well.

Best Regards

djtahl avatar Oct 19 '18 09:10 djtahl

news about this feature ???

renearaujo avatar Oct 25 '18 14:10 renearaujo

news?

pedrohills avatar Oct 25 '18 16:10 pedrohills

news?

joeson1 avatar Nov 22 '18 15:11 joeson1

Just as an experiment, I called snackbar.open with a custom panelClass: "snackbar-banner", which I put in my top level CSS as

snack-bar-container.mat-snack-bar-container.mat-snack-bar-center.snackbar-banner {
    width: 100vw;
    max-width: 100vw;
    border-radius: 0;
    padding: 8px 8px 8px 24px; /* Per Banner spec */
}
snack-bar-container.snackbar-banner simple-snack-bar {
    align-items: flex-end;
}
.snackbar-banner .mat-simple-snackbar-action {
    margin: 0 0 0 90px;
}

I believe this basically converts the snackbar styling to the Banner spec. You can just pass duration: 0 to keep it from automatically closing. This allows you to show a simple Banner with a single action. You could pretty easily use a custom component for the contents to support icons and a second action, to provide the full capabilities per the spec.

The bad news is that I can't figure out how to tell the Snackbar service to attach its Overlay to my main content component. As it stands, snackbars (and thus, this hacky snackbar-based "banner") always appear over top of my sidenav and can't push content down the way a banner is supposed to. If I could have it use the same overlay that my sidenav does (div.mat-drawer-backdrop) or just give it a parent component instance as its OverlayContainer, it would at least be closer to on-spec behavior for my use case. I'm doing more research into how to make this happen but I don't want to spend a ton of time on it.

thw0rted avatar Dec 21 '18 14:12 thw0rted

I realize it's impossible to implement every part of the Material spec for Angular, but I have to say I find it confusing that Angular Material has a "bottom sheet" component but no banner component, considering I don't think I've ever seen a website use a bottom sheet on desktop, whereas banners are pretty common on the web.

I'll try to implement a banner component myself, but I hope this one is on the Angular team's radar.

magnusbakken avatar Jan 30 '19 09:01 magnusbakken

I had to do it myself, in the end. I made a service, and an Outlet component that takes the service through injection and registers itself. The service exposes a method to show the component, with a message and some action button labels, and emits an event when one of the button is clicked. It was pretty straightforward, though I did wind up adding queueing logic to make sure that all calls to the service's open method will be shown eventually.

I found it easier to manually place a single instance of the Outlet component in my app -- in the right place, to make sure it opens over pannable content but under the sidebar / app toolbar -- than to try to make some kind of globally consistent logic for automatically inserting an overlay in the right place. I'm not sure that kind of design would fly in a library like this.

thw0rted avatar Jan 30 '19 12:01 thw0rted

@thw0rted Do you happen to have a code example? I'm trying to implement the same component

andrantis avatar Jun 17 '19 18:06 andrantis

It's not perfect, and I had to remove one or two references to other classes in my project, but this is what I'm using now. You just place one <banner-outlet></banner-outlet> in your app wherever the banner should be displayed. Based on the Material guidelines, I'm pretty confident that there's no way to automatically determine the right place for the outlet, so this seemed like the least-worst way to handle it. Mine is styled as position: relative; flex-grow: 0;.

ETA: to open the banner you inject the BannerService and call open("Banner message", ["OK", "Cancel", "Whatever"]) which returns an Observable that emits the array index corresponding to the clicked button. You don't have to call the init method, it's called from the component constructor; note that it will throw if you try to have more than one banner outlet per application.

thw0rted avatar Jun 18 '19 07:06 thw0rted

@thw0rted do you have a complete example that's open source? I understand if what you've done is closed source, but I'd love to see a stackblitz if you have one.

owenmecham avatar Jun 19 '19 18:06 owenmecham

It's part of a closed source project but I went ahead and pasted the relevant stuff into the Material2 doc example for Buttons. StackBlitz

This doesn't have all the styling in place but you get the general idea. There's no magic for positioning the resulting banner but the CSS needed isn't too complex.

thw0rted avatar Jun 20 '19 12:06 thw0rted

Another deficiency in support for the 'material' specification. Can we get an update on when this will be supported out-of-the-box?

stevebor1 avatar Jul 11 '22 18:07 stevebor1