angular 8 material dialog close button with X top right - html

I am trying to get my material dialog to have an X button at the top right, but I am having problems with the positioning.
component.ts
this.d.open(loginComponent, {
width: '300px',
height: '',
panelClass: 'dialogC',
});
component.html
<mat-dialog-content>
<button mat-button class="close-icon" [mat-dialog-close]="true">
<mat-icon>close</mat-icon>
</button>
<h2 mat-dialog-title>Login</h2>
style.scss
.dialogC {
position: relative !important;
}
.close-icon {
position: absolute;
top: 0;
right: 0;
transform: translate(50%, -50%);
}
The X is just aligned to the left instead of top right. Suggestions?
Update, this is the problem I get after adding flex:

<button class="close" mat-button (click)="onNoClick()">X</button>
<h1 mat-dialog-title>Login</h1>
<div mat-dialog-content>
...
...
</div>
CSS: (Please give it in global (styles.css) or give ViewEncapsulation.NONE or else these styles wont affect.)
.cdk-overlay-pane.my-dialog {
position: relative!important;
}
.close.mat-button {
position: absolute;
top: 0;
right: 0;
padding: 5px;
line-height: 14px;
min-width: auto;
}
Note that in the CSS We now have a new class out of thin air .my-dialog
So, please mention that as panelClass in dialogRef like below,
this.dialog.open(DialogComponent, {
width: '250px',
panelClass: 'my-dialog',
..
..
This yields me the following result,

The easy way now is:
<div mat-dialog-title class="dialog-title">
<h2>Title</h2>
<button mat-icon-button aria-label="close dialog" mat-dialog-close>
<mat-icon>close</mat-icon>
</button>
</div>
And the dialog-title css is
.dialog-title {
display: flex;
justify-content: space-between;
align-items: center;
}
That's working on Angular 8.0.0

Using mat-icon-button it is necessary to add only the style below to the button.
.close-button{
float: right;
top:-24px;
right:-24px;
}
Functional example:
stackblitz

You can have the X at the title and display: flex ? Like this,
<div mat-dialog-title class="flex-container">
<h1>Login</h1>
<button mat-button class="close-icon" [mat-dialog-close]="true">
<mat-icon>close</mat-icon>
</button>
</div>
<div mat-dialog-content>
...
...
</div>
FlexBox to the rescue,
.flex-container { display: flex;}
SideNote: You can still use fxLayout instead of .flex-container

In your component HTML file add the following markup at the top of all elements.
<div mat-dialog-title style="float: right; font-weight: 700; cursor: pointer;" (click)="close()">X</div>
In your component TS file add the close function as follows.
close(): void {
this.dialogRef.close();
}
Don't forget to include the dialogRef inside the constructor as an argument
constructor(public dialogRef: MatDialogRef<YourDialogComponent>) {}

What I prefer is doing something like this -
.html file
<button class="close" mat-button mat-dialog-title (click)="closeDialog()">X</button>
By giving mat-dialog-title to the button I make sure it is in the top layer and then I give custom class to it, something like
.css file
.close.mat-button {
position: inherit;
top: 0;
right: 0;
padding: 2px;
line-height: 3px;
min-width: auto;
}
The button discussed above and my modal-content is in a parent div, which I display as flex and use as flex-direction: column
.dialog{
display: flex;
flex-direction: column;
}
.ts file
closeDialog() {
this.dialogRef.close();
}```

You can acheive this by applying some css styles to mat-icon, you can achieve this.
Mat-dialog looks as below.
<button mat-icon-button class="close-button" [mat-dialog-close]="true">
<mat-icon class="close-icon" color="warn">close</mat-icon>
</button>
<h1 mat-dialog-title>Hi {{data.name}}</h1>
<div mat-dialog-content>
<p>Hello World!</p>
</div>
Add the following css rules
// if you want to change the color of the icon
.material-icons.color_white {color: #ffffff;}
.close-button{
float: right;
top:-24px;
right:-24px;
}
//if you want some css animation
.close-icon {
transition: 1s ease-in-out;
}
.close-icon:hover {
transform: rotate(180deg);
}
//To place the x mark outside of the container
::ng-deep .icon-outside .close-button{
float: right;
top:-52px;
right:-52px;
}
::ng-deep .icon-outside .mat-dialog-container {
overflow: unset
}
Your mat-dialog consuming componnet should look as below
constructor(public dialog: MatDialog) {}
openDialog(): void {
const dialogRef = this.dialog.open(DialogComponent, {
width: '250px',
panelClass:'icon-outside',
data: {name: 'your name'}
});
dialogRef.afterClosed().subscribe(result => {
console.log('The dialog was closed');
});
}
Adding custom class icon-outside is important.
This will change your code as expected.
If you are seeking to change the color of the icon, Add these two classes to mat-icon material-icons & color_white
So your button will look as below:
<button mat-icon-button class="close-button icon-outside" [mat-dialog-close]="true">
<mat-icon class="close-icon material-icons color_white">close</mat-icon>
</button>

I just ran into the same problem. I've come up with an easier solution using floats. This also aligns the close X with the title, which I find more visually pleasing.
HTML file:
<div>
<h1 mat-dialog-title style="float: left">Dialog Title</h1>
<span style="float: right" [mat-dialog-close]>X</span>
</div>
<div mat-dialog-content style="clear: both">
...
</div>

On our project I did an implementation using flex and css.
.html file
<div fxLayout="column">
<div fxLayoutAlign="end">
<button mat-icon-button color="primary" (click)="close()"><mat-icon>close</mat-icon></button>
</div>
<mat-card class="pd-2">
...
</mat-card>
</div>
.ts file
openMinimumsModal( ) {
const dialogRef = this.matDialog.open(OrderMinimumsComponent, {
width: 'auto',
panelClass: 'dialog-no-padding',
data: { ... },
});
dialogRef.afterClosed().subscribe(() => {});
}
close(): void {
this.dialogRef.close();
}
.css file
.dialog-no-padding .mat-dialog-container {
padding: 0;
}
.pd-2 {
padding: 0 20px 20px 20px !important;
}

Possible duplicate: 49420069
Close functionality and button alignment without TypeScript.
HTML:
<button class="button-close" mat-button [mat-dialog-close]="true">X</button>
CSS:
.button-close {
justify-self: right;
font-size: 20px;
border: none;
height: 30px;
background-color: #FFFFFF;
outline: none;
color: #c04747;
&:hover {
cursor: pointer;
}
}

Related

How can I make dropdown menu items width exactly the width of the content?

I am using Reactstrap drop-down menu:
import React from "react";
import {
Dropdown,
DropdownToggle,
DropdownMenu,
DropdownItem,
} from "reactstrap";
export default class DropDownTest extends React.Component {
constructor(props) {
super(props);
this.toggle = this.toggle.bind(this);
this.state = {
dropdownOpen: false,
};
}
toggle() {
this.setState((prevState) => ({
dropdownOpen: !prevState.dropdownOpen,
}));
}
render() {
return (
<Dropdown isOpen={this.state.dropdownOpen} toggle={this.toggle}>
<DropdownToggle caret>test</DropdownToggle>
<DropdownMenu>
<DropdownItem>A</DropdownItem>
<DropdownItem>A</DropdownItem>
<DropdownItem>A</DropdownItem>
<DropdownItem>A</DropdownItem>
</DropdownMenu>
</Dropdown>
);
}
}
The problem is the DropdownItem width is too large for what I am trying to display the letter A:
I'd like the width of the DropdownItem to be the same of the required width by the inner element. In this case the letter A.
When I inspect the dropdown menu, this is what I see:
<div
tabindex="-1"
role="menu"
aria-hidden="false"
class="dropdown-menu show"
style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(515px, 41px, 0px);"
x-placement="bottom-start"
>
<button
type="button"
tabindex="0"
role="menuitem"
class="dropdown-item"
>
A
</button>
<button
type="button"
tabindex="0"
role="menuitem"
class="dropdown-item"
>
A
</button>
<button
type="button"
tabindex="0"
role="menuitem"
class="dropdown-item"
>
A
</button>
<button
type="button"
tabindex="0"
role="menuitem"
class="dropdown-item"
>
A
</button>
</div>
These are the relevant CSS classes:
.dropdown-item {
display: block;
width: 100%;
padding: 0.25rem 1.5rem;
clear: both;
font-weight: 400;
color: #212529;
text-align: inherit;
white-space: nowrap;
background-color: transparent;
border: 0;
}
And I believe this one is defined in the template that I am using:
.dropdown-menu .dropdown-item {
color: #66615b;
font-size: 14px;
padding: 10px 45px 10px 15px;
clear: both;
white-space: nowrap;
width: 100%;
display: block;
}
I tried to remove the padding:
<DropdownItem className="p-0" >A</DropdownItem>
<DropdownItem className="p-0" >A</DropdownItem>
<DropdownItem className="p-0">A</DropdownItem>
<DropdownItem className="p-0">A</DropdownItem>
But, this did not change much as expected.
Any idea how to achieve my goal?
Bootstrap puts a min-width of 10rem on dropdowns (not dropdown items, which should remain 100% width). I determined this by inspecting the elements in my browser's document inspector. Dropdowns actually do take the width of their content over that 10rem minimum. I guess the Bootstrap team just thought skinny dropdowns looked odd.
You can override this using your custom CSS strategy and a custom class. Including the dropdown-menu class in the selector will ensure precedence.
.dropdown-menu.min-width-0 {
min-width: 0;
}
I assume you'd apply this to the DropdownMenu component. The className property is listed in the ReactStrap docs for that component.
<DropdownMenu className="min-width-0">

How can I update the font size and background color of my Tooltip and make its icon smaller?

I have tried for hours to get this to work trying multiple solved stack solutions and none have worked.
I am assuming I am either missing something or I have my divs/spans incorrect. Any help would be greatly appreciated. Currently my text is very small and bg color is grey and slightly transparent.
Also if it is possible to make the "info" icon smaller that would be great as well. Thank you!
.mainContainer {
width: 40%;
float: left;
}
.info {
display: flex;
}
.info .span {
align-self: center;
}
.info-button{
padding: 0;
border: none;
background: none;
outline: none;
background-color: transparent;
top:-10px;
}
<div class="mainContainer">
<h3>Main Title</h3>
<div class="info">
<h5>Title</h5><span class="info-span">
<button mat-icon-button class="info-button" #tooltip="matTooltip" matTooltip="Tooltip Text">
<mat-icon color="basic" >info</mat-icon>
</button>
</span>
</div>
</div>
Try this
::ng-deep .mat-tooltip {
background-color: transparent;
font-size: 12px;
}
You can set !important if not working.
Hope useful
You can use popper js to integrate and style tooltips it's easy and simple :
this is a quick exemple from the documentation :
<!DOCTYPE html>
<title>Popper example</title>
<style>
#tooltip {
background-color: #333;
color: white;
padding: 5px 10px;
border-radius: 4px;
font-size: 13px;
}
</style>
<button id="button" aria-describedby="tooltip">I'm a button</button>
<div id="tooltip" role="tooltip">I'm a tooltip</div>
<script src="https://unpkg.com/#popperjs/core#2"></script>
<script>
const button = document.querySelector('#button');
const tooltip = document.querySelector('#tooltip');
// Pass the button, the tooltip, and some options, and Popper will do the
// magic positioning for you:
Popper.createPopper(button, tooltip, {
placement: 'right',
});
</script>
or visit the official website to learn about popper js :Tutorial

Angular mat-list-item button in one line with text

I want to change my icon to a button to use it as copy to clipboard method. But when I do it, the button moves to the right side. Only when I try a around the text it works but of course the formatting is broken.
<mat-list>
<h3 matSubheader>Persönliche Daten</h3>
<mat-list-item>
<button mat-icon-button ngxClipboard [cbContent]="firstname">
<mat-icon matListAvatar>account_box</mat-icon>
</button>
<h4 matLine>{{firstname}}</h4>
<p matLine>Vorname</p>
</mat-list-item>
<mat-divider [inset]="true"></mat-divider>
<mat-list-item>
<mat-icon matListAvatar>description</mat-icon>
<h4 matLine>{{lastname}}</h4>
<p matLine>Nachname</p>
</mat-list-item>
</mat-list>
My CSS:
mat-list-item mat-icon[matListAvatar], .mat-list-item-content mat-icon[matListAvatar] {
background-color: rgba(0,0,0,0.04);
}
mat-list-item mat-icon[matListAvatar], .mat-list-item-content mat-icon[matListAvatar] {
align-items: center;
align-content: center;
justify-content: center;
display: flex;
}
/deep/ .mat-list-item-content {
padding: 0!important;
}
/deep/ .mat-list-base .mat-subheader {
padding: 0!important;
}
p {
font-family: Lato;
color: rgba(0,0,0,.54);
}
Using the (click) property
You can just make the icon behave like a button.
Add a (click) property to it and call the function you want!
<mat-icon (click)="myFunction($event)" matListAvatar>account_box</mat-icon>
Then you can add some :hover css to it to make it feel like a button.
Using HTML/CSS
You can place any content next to the button in a wrapper, you can customize this one in the css to behave differently if needed (if you end up adding more data to display you might have to play around with the flex properties, margin... or you might need to have nested wrappers, etc...)
<button mat-icon-button >
<mat-icon matListAvatar>account_box</mat-icon>
</button>
<div class="test-wrapper">
<h4 matLine>{{firstname}}</h4>
<p matLine> Vorname</p>
</div>
with this css:
.test-wrapper{
padding-right: 0;
padding-left: 16px;
width: 100%;
display: flex;
flex-direction: column;
}
.test-wrapper > *{
margin: 0;
}

Angular mat-form-field will not widen

Summary:
I want to widen the input box on my page.
When I Inspect, on the screen it says "div.mat-form-field-infix 300x51.5 and on the right it says a width: 180px;
The actual input box says 300x24
Tried:
After looking at angular 5 material - form fields stuck at 180px I tried the following:
<mat-form-field style="width:500px !important">
Then I tried:
.input-full-width {
width: 400px;
}
.
<mat-form-field class="input-full-width">
Then I tried:
.mat-form-field-infix {
width: 480px;
}
Code:
CSS:
#import '../../../../form-elements.css';
.l-card {
width: 80%;
max-width: 80rem;
}
.logo > img {
display: block;
max-height: 7rem;
max-width: 30rem;
margin: 1rem auto 3rem auto;
}
.mat-radio-button {
display: block;
margin: 1rem auto;
}
.mat-radio-button > ::ng-deep.mat-radio-label {
white-space: normal;
word-break: break-all;
align-items: flex-start;
}
#media screen and (min-width: 1000px) and (min-height: 600px) {
.l-card {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
margin: 0;
}
}
.example-container {
display: flex;
flex-direction: column;
}
.example-container > * {
width: 500px;
}
HTML:
<div fxLayoutAlign="center center" *ngIf="!isLoad">
<mat-spinner></mat-spinner>
</div>
<div *ngIf="isLoad">
<p>
Would you prefer to receive the verification code by text message or by email?
</p>
<form [formGroup]="_form">
<div class="center-and-left">
<mat-radio-group>
<mat-radio-button (change)=sO($event) value="phone">Text {{ phone }}</mat-radio-button>
<mat-radio-button (change)=sO($event) value="email">Email {{ email}}</mat-radio-button>
</mat-radio-group>
</div>
<button type="button" mat-raised-button color="primary" (click)="sendC()" [(disabled)]="isDisabled" >Send Code</button>
<div fxLayoutAlign="center start" *ngIf="!isLoaded && showSpinner">
<mat-spinner></mat-spinner>
</div>
<div *ngIf="isLoaded">
<br />
<div class="example-container">
<mat-form-field>
<input matInput (keyup)="someCode($event.target.value)" (keyup.enter)="onSubmit()" type="number" max="6" min="6" placeholder="Please enter verification code" formControlName="code" required>
</mat-form-field>
</div>
<p *ngIf="failedVerfication" class="error">Verification failed. Please retry or press Send Code to have a new code sent to you.</p>
<button mat-raised-button color="primary" type="button" (click)="onSubmit()" [disabled]="isDisabledSubmit">Verify and Sign In</button>
</div>
Expected: To widen the input box
Actual: No change
Try ng-deep to replace the existing style
html code:
<mat-form-field class="width-480"></mat-form-field>
css code:
::ng-deep .width-480{
width: 480px;
}
I guess it's an year late to answer, but the answer is a small change from what Imrul's answer says.
Try ng-deep with !important to override the style and apply whatever the default style is.
::ng-deep .width-480{
width: 480px !important;
}
This would definitely give your expected answer and widen it.

ANGULAR 2: Floating button not floating CSS

Im very new to frontend development & angular 2. I was trying to program a floating button on the right bottom of the webapp that would allow users to open the shopping cart if needed (cart-button). The problem I have is that the button appears on the screen, put it does not readjust its position once scrolled down, its position is fixed to one spot and it wont move.
HTML:
<md-sidenav-container class="example-container">
<md-sidenav #sidenav class="example-sidenav">
<div class="scroll">
<md-card *ngFor="let ticket of shoppingCart">
<md-card-title>{{ticket.product.name}}</md-card-title>
<md-card-subtitle>$ {{ticket.product.price}}</md-card-subtitle>
<md-card-subtitle>Quantity: {{ticket.quantity}}</md-card-subtitle>
<button md-icon-button (click)="removeProduct(ticket.product)">
<md-icon>delete</md-icon>
</button>
</md-card>
<button md-button class="checkout" (click)="openDialog()">CHECKOUT</button>
</div>
</md-sidenav>
<div id="cart-button">
<button md-icon-button (click)="openNav(sidenav)" id = "cart-button2">
<md-icon>shopping_cart</md-icon>
</button>
</div>
<app-banner *ngIf="!featured"></app-banner>
<form *ngIf="!featured" class="cont">
<md-input-container class="search">
<input mdInput placeholder="Search" type="text" (keyup)="onKeyUp(search.value)" #search>
</md-input-container>
<md-select placeholder="Categories" class="category">
<md-option *ngFor="let category of categories" (click)="change(category)">
{{ category }}
</md-option>
</md-select>
</form>
<md-grid-list cols="5" rowHeight="1:1.4" class="size">
<md-grid-tile *ngFor="let product of products" class="separation">
<md-card class="example-card">
<md-card-header>
<div md-card-avatar class="example-header-image"></div>
<md-card-title>${{product.price}}</md-card-title>
<md-card-subtitle>{{product.name}}</md-card-subtitle>
</md-card-header>
<div class="image-container" [ngStyle]="{'background-image': 'url(' + product.imgUrl + ')'}" [routerLink]="['/product', product.id]">
</div>
<md-card-actions>
<button md-button (click)="addToCart(product.id, 1, sidenav)">ADD TO CART</button>
</md-card-actions>
</md-card>
</md-grid-tile>
</md-grid-list>
<div id="fidget-spinner-container" *ngIf="firstLoad">
<md-spinner id="fidget-spinner" *ngIf="!featured"></md-spinner>
</div>
</md-sidenav-container>
CSS:
.size {
width: 1400px;
margin:100px auto;
}
.example-card {
box-shadow: 0 4px 8px 0 rgba(0,0,0,.3);
transition: 0.3s;
width: 400%;
border-radius: 5px;
}
.example-card:hover {
box-shadow: 0 10px 20px 0 rgba(0,0,0,0.5);
}
.example-header-image {
background-image: url('https://img2.hkrtcdn.com/1434/prd_143361_c_l.jpg');
background-size: cover;
}
.example-container {
position: relative;
width: 100%;
height: 100%;
border: 1px solid rgba(0, 0, 0, 0.5);
}
.example-sidenav-content {
display: flex;
height: 100%;
align-items: center;
justify-content: center;
}
.example-sidenav {
padding: 100px 50px 0 50px;
width: 250px;
}
.checkout {
bottom: 30px;
position: fixed;
}
.image-container {
width: 200px;
height: 200px;
background: white center no-repeat;
background-size: contain;
}
.mat-card-image:first-child {
margin-top: 0 !important;
}
.example-card {
margin:15px;
}
.scroll {
overflow-x: auto;
width:100%;
height:80%;
}
.cont {
width:70%;
padding-right:15%;
padding-left:15%;
padding-top: 330px;
display: inline-flex;
}
.search {
width:70%;
padding-left:10%;
/*margin-left: 30%;*/
/*margin-right: 30%;*/
}
#fidget-spinner {
margin:auto;
padding-bottom:50px;
}
.mat-option {
color: black;
}
#cart-button {
position:fixed;
width:60px;
height:60px;
bottom:40px;
right:40px;
background-color: #666666;
color:#FFF;
border-radius:50px;
text-align:center;
box-shadow: 2px 2px 3px #999;
}
.cart-button2 {
margin-top:22px;
}
.category {
padding-right:10%;
padding-top: 10.4px;
width:20%;
}
What I do typically is this in my main module component:
template: `
<div class="container-fluid" [ngStyle]="containerDivSize">
<router-outlet>
</router-outlet>
</div>
`,
So the template above for the container defines the div to be exactly the size of the screen, and by way of setting an Observer on window resize events below, containerDivSize adapts to changes in the window size and orientation, so if the user resizes the window we get the updates. This means we know the exact pixel dimensions of the screen, and we size our containing div to fill the window regardless of any changes.
containerDivSize: any;
constructor(){}
ngOnInit() {
Observable.fromEvent(window, 'resize')
.map(getWindowSize)
.subscribe(
windowSize$ => {
var windowHeight = windowSize$.height;
var windowWidth = windowSize$.width;
this.containerDivSize = {
'height': windowHeight + 'px'
'width': windowHeight + 'px'
}
});
}
You can use this same method to define a button position style that takes the window width and height, subtract the button size and apply it to your button, which will always stay fixed just inside the bottom right corner of the window no matter what the user does (scroll or resize the window).
Maybe something like this:
buttonPosition: any;
var buttonVerticalPosition = windowSize$.height-50;
var buttonHorizontalPosition = windowSize$.width-120;
this.buttonPosition = {
'position': 'absolute',
'top': buttonVerticalPosition + 'px',
'left': buttonHorizontalPosition + 'px'
}
Then add that class to your button.
<button class="btn btn-sm btn-default buttonPosition" >View Cart</button>
The problem is you are using Materal2 which is using transform3D in its style. Due to this relative postion is not working. You should place your button in this component. It takes whatever you put in it and places it in the body.
Other solutions are registering to a scroll event and re-setting the position everytime. This results in poor performance on mobile.