feat(tooltip): add support for rich tooltips
QuentinFchx opened this issue ยท 46 comments
Bug, feature request, or proposal:
Feature request
What is the use-case or motivation for changing an existing behavior?
Popovers are not part of the current material design spec, however they are a common component in desktop applications.
It got some traction last year within the angular/material repository here and here.
If this is still not acceptable, what are the alternatives?
I started to hack a bit on the mdDialog
, using a custom positioning strategy and custom css for the directional arrow but I'm not sure this is the way-to-go.
Thank you in advance!
Shouldn't be hard, it's basically the same thing as menu, when it comes to positioning and usage of the overlay service, the only difference is that instead of menu items it would have content and buttons. But as you said, it's not part of the spec, so you'd be better off doing it yourself.
I've already mentioned it in some issue, but I think this repo could maintain a curated list of user created components utilising m2's helper services and themes, that meet the quality requirements and standards of this repo.
When I think about it, it would be nice to have a "custom-material2-component-starter" repo, which would include a single component and have everything set up(the way to hook into the themes, services tests etc) along with a guide of requirements, to be considered high quality and worthy of inclusion in the above mentioned list.
Thoughts @jelbourn @devversion ?
@fxck So you are saying that we should have for each component a single starter repository?
Nope, what I meant is that you could create a "starter" repository that one could clone and create custom material2 component(like popover) with, with everything set up.
Basically this repository slimmed down with different .md files and one example component and material2 as dependency(also addressing the fact that the utility functions would be imported from @angular/material rather than from ../core/rtl/dir for example).
We don't have any plans to add / accept a feature like this before 2.0.0 final, though it's something we may explore in the future.
I've just created an example popover component, and you can view demo here and the source here it has basic documentation on how to use. If you want to view the demo source you can find that here. It's using most of the menu component with a few things added/removed. It is not complete it was to give you an example. If I have time, I'll rewrite it with more functionality and consistent options naming.
Standard popover
Google+ style popover
Have a play using the StackBlitz template.
After many people contacting me requesting me to publish my demo as a library, I found some time this week to publish it. You can find the GitHub page here https://github.com/material-extended/mde and NPM package here https://www.npmjs.com/package/@material-extended/mde
Have a play using the StackBlitz template.
@joejordanbrown thanks for the nice lib, but thinking about this again - I believe I can do some of the things with dialog and css (maybe I am just naive;) but can not change animations (well, to my knowledge and effort;) - are animations customizable on you popup? Thank you
@honzajde thanks. You could, but it's constrained and would not be a popover. A popover is meant to position itself to the target element, and it is also activated via other events than just click, you also have focus trapping that can be disabled if required. The example here shows a few use cases, and I will be pushing an updated demo soon with more advanced examples, like using with form inputs on focus and blur etc.
Currently, it doesn't allow for custom animations, that's more of an Angular problem. I'm sure this will be resolved in the future though. What type of animation was it that you required?
as for the animation - just a simple one but defined by me or my organization, but as long as it looks very 'materially' (and it does) and the speed is ok, I will not need to change it. I hope this popup will make it in some form among standard angular material components. Thx
@jelbourn @mmalerba is anyone actually working on this? Given the intern project
tag.
Menu, select, datepicker, autocomplete all could be reusing the same base.
I think menu is closest to the popover component, the problem I see with it is that a lot of logic is actually in the trigger, which only supports click.
Menu, select, datepicker, and autocomplete already share the same base (overlay w/ connected position strategy).
Adding a tooltip-like popup/bubble is on our backlog but isn't scheduled.
FWIW we've also opened up the popover component we're using internally. It's only depends on the CDK and has a very flexible api.
https://github.com/ncstate-sat/popover
https://stackblitz.com/edit/sat-popover-examples
Hopefully this will help carry some people over until an official Material release.
any news here
Does anyone have a suggestion for a component, ng material 2 vanilla or custom made, that allows you to set menu position to mouse? For example, I got a really fat table that I want to generate a menu of on click of a row.
Additionally, none of the components I'm looking at have an api that allows for pixel perfect setting in relation to the component that you birth the menu from. If there was, I can just save the mouse position and open the menu at that exact location.
@willshowell will your popover component be added to official M2 modules?
Really good thread, I would also throw in my hat for a popover component. PrimeNG has one called OverlayPanel we use very often. Any timeline on when we might see this component in Angular Material?
This is my simple solution where i emulate a PopOver with Material Design Menu (no extra dependencies
,no cdk, just angular/material). I used this solution in a project for a customer of mine.
@jelbourn any near future plans about Popover?
I've just check Google Maps and it looks like this kind of control is used there (with that little triangle on top):
While waiting for official implementation I've found this component. Hope this help others.
We don't have any plans to add / accept a feature like this before 2.0.0 final, though it's something we may explore in the future.
Well now the version is a way beyond 2.0.0 :) if I remember that it is to catch-up with angular versioning (?) but, still, any more concrete plans on that?
I tried a different solution (this, a wrapper for tippy.js etc), but finally came up with a simple CSS solution with delay hover event, maybe would be helpful for somebody
HTML:
<div [ngClass]="{'needHover':true}> some text
<span class='tooltip'>Tooltip custom html </span>
</div>
SCSS:
span {
position: absolute;
transition: 0s;
opacity: 0;
}
&:hover > span {
opacity: 1;
transition-delay: 0.5s;
background: white;
padding: 20px;
box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2),
0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
width: 300px;
min-height: 200px;
color: black;
}```
how to set popover to stay open.
I ended up doing something like this:
HTML:
<ng-template #infoPopup>
<mat-card class='info-card'>
<div class='mat-title'>{{param.name}}</div>
<mat-card-content>
<div><b>Description: </b>{{param.longDescription}}</div>
</mat-card-content>
</mat-card>
</ng-template>
<button mat-icon-button type='button' #infoButton (click)='openInfoOverlay(param, infoButton, infoPopup)'>
<mat-icon class='info-icon'>info</mat-icon>
</button>
and then use CDK overlay to display the template:
private overlayRef: OverlayRef;
constructor(private overlay: Overlay, private viewContainerRef: ViewContainerRef) {}
ngOnDestroy() {
this.closeInfoOverlay();
}
openInfoOverlay(param: ParameterDescriptor, relative: MatButton, template: TemplateRef<any>) {
this.closeInfoOverlay();
this.overlayRef = this.overlay.create({
positionStrategy: this.overlay.position().flexibleConnectedTo(relative._elementRef).withPositions([{
overlayX: 'end',
overlayY: 'bottom',
originX: 'center',
originY: 'top'
}]).withPush().withViewportMargin(30).withDefaultOffsetX(37).withDefaultOffsetY(-10),
scrollStrategy: this.overlay.scrollStrategies.close(),
hasBackdrop: true,
backdropClass: 'info-backdrop'
});
this.overlayRef.backdropClick().subscribe(() => this.closeInfoOverlay());
const portal = new TemplatePortal(template, this.viewContainerRef);
this.overlayRef.attach(portal);
}
closeInfoOverlay() {
if (this.overlayRef) {
this.overlayRef.detach();
this.overlayRef.dispose();
this.overlayRef = null;
}
}
and last but not least some CSS to get an arrow on the popup and make the backdrop for the popover invisible:
.info-backdrop {
opacity: 0;
}
.info-card {
max-width: 300px;
}
.info-card::after {
content: "";
position: absolute;
box-shadow: rgba(0, 0, 0, 0.3) 2px 2px 2px ;
transform: rotate(45deg);
top: calc(100% - 10px);
right: 25px;
margin-left: -10px;
border-width: 10px;
border-style: solid;
border-color: transparent #FFF #FFF transparent;
}
just wrap menu into a popover. simple but works in 90% of cases. https://stackblitz.com/github/maxisam/ngx-mat-popover
do we have news? This functional lack is really heartbreaking.
I made mine without any other external librairies.
(and I made an exemple with popover content can be a custom-component)
<mat-icon [matMenuTriggerFor]="menu">{{matIconSelection}}</mat-icon>
<mat-menu #menu="matMenu">
<div mat-menu-item [disableRipple]="true" (click)="$event.stopPropagation()">
<ng-content></ng-content>
</div>
</mat-menu>
a little bit of css, in your css component file :
mat-icon {
cursor: pointer;
}
.mat-menu-item {
height: inherit;
width: inherit;
cursor: default;
}
Just add in your popover component the input :
@Input() matIconSelection: string;
And the example of use :
<home-made-popover [matIconSelection]="'info'"> <div> <div>test</div> <custom-component></custom-component> </div> </home-made-popover>
Hope it can help
Does https://material.angular.io/cdk/overlay/overview meet the needs here?
If not, what is missing? more documentation? a component that simplifies that API and adds Material Design styles?
@Splaktar Hi, a component like you say would be nice. For the moment we use "@ncstate/sat-popover": "4.0.0"
Does https://material.angular.io/cdk/overlay/overview meet the needs here?
If not, what is missing? more documentation? a component that simplifies that API and adds Material Design styles?
I think that sums it up. Simplified API and more material-esque styling and transition animations. From an api perspective, something similar to the mat-dialog api might be appropriate, allowing the ability to pass components in, and subscribe to closure and action events.
How to change position of popover? And also how to make the popup fixed instead of movement while scrolling?
Why do we have this Popover for React but not for Angular ? https://material-ui.com/components/popover
@fosteman let me take a really wild guess, but could it perhaps be because angular/components
and mui-org/material-ui
are completely different packages managed by completely different people and have absolutely nothing to do with each other, other than being based on material design spec by google?
@fosteman let me taky a really wild guess, but could it perhaps be because
angular/components
andmui-org/material-ui
are completely different packages managed by completely different people and have absolutely nothing to do with each other, other than being based on material design spec by google?
I just see that this issue is 3 years old, a bit discouraging, and it seems like mui-org/material-ui
is releasing so many more components every new version (v5
is coming up)
I definitely don't want to compare the two packages head-to-head, but I have to look for 3rd party popover module for my angular app.
@fxck what do you think makes it so ?
That's because this is the official implementation made by Angular, so they spend a lot of time trying to make it compatible, accessible, well tested, well documented, 100% matching the official spec down to the animation speed (or I guess they try, at the moment every component is basically using outdated specs.) etc. Nothing is really made without a prior big analysis document, all this with a limited team size. A Team that on top of that spends time doing everything but adding new features, like rewriting the whole thing to use mdc web components and team that doesn't really accept community contributions (when it comes to features like this).
So yeah, mui on the other hand has none of this burden. Luckily popover is easy enough to create using cdk, sure official implemention would be nice, but there are community components that are good enough.
I should probably write a blog post about this or something, but a big (maybe the biggest) part of what our team spends time on is not breaking downstream apps inside Google. All of google is one massive repo, so every library can only have one version available for the whole company. It's the responsibility of infrastructure teams (us) to not break any applications whenever we merge a change, and it's incredibly easy to "break" someone because most applications have screenshot gold tests, and many have relatively brittle unit tests that assume a certain DOM structure or sync/async behavior. This means that even a change as trivial changing the border-radius on a button takes far more than than most people would expect. Our recent/current priorities (test harnesses, MDC-based components) are investments to make this process easier. The test harnesses help avoid the problem of people writing brittle unit tests that break whenever we change anything. The MDC-based components offloads a lot of the responsibility for updating pixels to Google's Material Design team.
I want to pursue new features more than anyone (hello cdk combobox and menu), but the work we're prioritizing instead is going to have a much bigger effect on our velocity in the long run.
Inclusive Design methodologies span across devices as well as libraries, it's a hard work and this is what makes Google "inclusive" to it's users, making them feel heard and seen. Thanks for doing this @jelbourn, blogpost would be amazing!
Why do we have this Popover for React but not for Angular ? https://material-ui.com/components/popover
I have built a material extensions library, you can try this one Popover.
Why do we have this Popover for React but not for Angular ? https://material-ui.com/components/popover
I have built a material extensions library, you can try this one Popover.
That's actually pretty nice. Have you considered contributing it back to this project as a new component?
Popovers are not part of the current material design spec, however they are a common component in desktop applications.
I'm surprised to see that and nobody to tell it's wrong. Maybe the spec has been updated so let me add some content here, because the popover actually exists in the spec. It's actually called rich tooltip. See it here: https://material.io/components/tooltips/web#rich-tooltips
Of course it also exists in MaterialUI 3 : https://m3.material.io/components/tooltips/overview
The problem with most of the community solutions is accessibility. I must have tried close to 10 different solutions and even on the ones that weren't abandoned and still had working demos, most of them were completely inaccessible with a keyboard. The only one I found that works well is https://github.com/ncstate-sat/popover, so big thanks to @willshowell!
I don't think you can just use the CDK Overlay without some handling of focus in and out, tab trapping, etc.
Actually, I found it hard to even find this page, because there doesn't seem to be a standard name for these things (popup, popover, overlay, non-modal-dialog, dropdown, rich tooltip, etc.).
P.S. Google themselves make heavy use of this type of control here: https://www.google.com/travel/hotels
Angular material rich tooltips would be a great addition to this library, even if experimental under the MDC namespace
Any updates on this?
Why is this not a higher priority given the long history of this and many other related issues, not to mention the clear precedent set by Material 3's Rich Tooltips.
To my mind this seems more like a P2 issue, "The issue is important to a large percentage of users, with a workaround." The community demand is clear.
I wonder if the new popover API might make it that much easier to build this (https://developer.chrome.com/blog/introducing-popover-api/) Though, I guess expansive browser support isn't quite there yet for it.
Any updates?
This is also something that I'd like to take advantage of. My opinion is that if it's going to be made a standard in M3 then it should be included in Angular Material.
Technically M3 tooltips have been implemented, just not in Angular (unless you count Wiz):
https://contacts.google.com/ (on other contacts)
That's nice, but doesn't exactly help us here.