I am trying to add a button to a mat-list-item. This is my current HTML template code:
<mat-selection-list
[multiple]="false"
[class.selected]="currentItem"
formControlName="itemListControl"
>
<mat-list-option
*ngFor="let item of items"
[value]="item.id"
>
<div style="display: flex; justify-content: space-between; align-items: center">
<div style="display: flex; align-items: center">
{{ item.name }}
</div>
<button mat-icon-button>
<mat-icon>edit</mat-icon>
</button>
</div>
</mat-list-option>
</mat-selection-list>
When I inspect the site in my browser, I can see that there is a 16px padding which moves the button to the left inside the list item:
I already tried removing it by adding this to my scss file for the component:
.mat-list-item {
padding-right: 0 !important;
}
For some reason, this does not have any effect. It seems like this is not even applied at all to the element. What am I doing wrong and how can I get rid of this padding (without causing any potentially bad side effects)?
Please use like below. It would work.
.mat-list-text {
padding-right: 0 !important;
}
Thanks!
Use the whole selector(instead of just .mat-list-text, copy all the selector part of the css highlighted in the image above) to remove the the padding, angular material is very hard to modify. Dont forget to add the !important aswell. I had to do this previously. I hope it will work for you aswell.
Related
I have a list of elements. Every element is displayed on a row. How can I display four elements on a row?
My code is:
<div class="form" id="skillsList">
<mat-label>Choose skills</mat-label>
<mat-selection-list #skills>
<mat-list-option *ngFor="let skill of listOfSkills">
{{skill}}
</mat-list-option>
</mat-selection-list>
</div>
It looks like mat-list-option has display: block. So you can override that to get them to display however you want. For example:
<mat-list-option ngFor="let skill of listOfSkills"
style="display:inline-block; text-align:center;">
{{skill}}
</mat-list-option>
or using CSS:
mat-list-option {
display:inline-block !important;
text-align: center;
}
This is what you're going to want to do if you want exactly 4 per line as you had originally stated.
<div class="form" id="skillsList">
<mat-label>Choose skills</mat-label>
<mat-selection-list style="display: flex; flex-wrap: wrap" #skills>
<mat-list-option *ngFor="let skill of listOfSkills; let i = index" [attr.data-index]="i">
{{skill}}
<div *ngIf="i%4" style="flex-basis:100%;"></div>
</mat-list-option>
</mat-selection-list>
</div>
All you're doing is adding a modulo operator that triggers after every fourth item to break the line. The flex-wrap and display flex are to allow you to put flex basis on the div with the *ngIf
The sample code:
<div>
<mat-list fxLayout="row" dense>
<mat-list-item *ngFor="let label of labelsList"> <!-- just an array of strings -->
<button mat-button>
<mat-icon>cloud</mat-icon>
{{label}}
</button>
</mat-list-item>
</mat-list>
</div>
The result:
When I resize the browser window:
What I need: the buttons that don't "have room" to simply go on the next row.
How do I achieve this? I tried several combinations of CSS classes, properties, etc... nothing worked.
LATER EDIT: here's a complete reproducible example: https://angular-svt72k.stackblitz.io
mat-list-item is by default using the full width of its container and setting each item as display: block. To overrule this, you need to override the default Angular (Material) styling that comes with <mat-list>.
Setting .mat-list-test to display: flex and adding flex-flow: row wrap will make it go to the next line when there's not enough space available. Next to that, as said, the .mat-list-item styling is taking the full width. You can override it by setting display: initial and width: auto. Read more about flexbox at MDN.
CSS
.mat-list-test {
display: flex;
flex-flow: row wrap;
}
.mat-list-base .mat-list-item.mat-list-item-test {
display: initial;
width: auto;
}
See this example on StackBlitz to show the outcome.
I'm working in a project where we have implemented ng-bootstrap and I'm now working on the toast-component and to it more suitible for our company.
What I'm trying to achive right now is to make a button inside of the toast to be on the far right while the text will be on the left. Right now the button comes directly after the text, which leaves a lot of space to the right of the button.
In the documentation (https://ng-bootstrap.github.io/#/components/toast/overview) they say:
We provide a dedicated ngb-toasts CSS class you could use, or write your own styles in case some specificities would be needed.
However per my understanding is that it only styles the toast it self and not the things inside of it, which is what I want to do.
I'm trying to achive this by adding in flexbox
SCSS
.toast {
display: flex;
flex-direction: row;
justify-content: space-between;
.text,
button {
align-self: center;
}
}
HTML
<ngb-toast *ngFor="let toast of toastService.toasts" [class]="toast.classname" class="toast">
<ng-template [ngIf]="isTemplate(toast)" [ngIfElse]="text" class="text">
<ng-template [ngTemplateOutlet]="toast.textOrTpl"></ng-template>
</ng-template>
<ng-template #text class="text">
<span>
{{ toast.textOrTpl }}
</span>
</ng-template>
<button class="btn ml-2" [class]="toast.classname" (click)="toastService.remove(toast)">
{{toast.button}}
</button>
</ngb-toast>
When I build the application and runs it, I can see in the browsers devtool that ng-bootstrap has added a new div with class="toast-body".
First question I have is why does it get added and for what reason?
This new div then contains my text and my button, which means that the they aren't affected by my flexbox that I added in the (now parentclass to toast-body).
I tried to address this issue in a simple way by adding in the newly created div in my style.css as well.
SCSS
.toast {
& >.toast-body {
display: flex;
flex-direction: row;
justify-content: space-between;
.text,
button {
align-self: center;
}
}
}
Sadly this approach doesn't work, the styles aren't hitting <div class="toast-body">.
What do I need to change / do in order to get the result I want?
How can I make sure that my styles trigger <div class="toast-body"> and the content inside of the div?
The goal
I'm trying to write my own search bar for mat-table. The search bar consists only of inputs - one for each column. I placed it right above the table and now I'm trying to distribute them equally with the help of flex-layout, like the table does with its columns.
The problem
But the problem is that those inputs don't listen to me and don't shrink but they overflow outside the wrapping element. I need them to shrink equally to fit in the wrapping section but I don't know how to do this.
The code
Here is the sample of the code I wrote so far:
<section fxLayout="row" class="search-table" style="overflow-x: auto;">
<mat-form-field *ngFor="let item of items" fxFlex>
<input matInput type="text" placeholder="sample text" fxFlex>
</mat-form-field>
</section>
.search-table {
border: 1px solid black;
}
EDIT
Here's stackblitz example of my problem. Flex-layout don't work there for some reason so I added flex to css.
The problem comes from the .mat-form-field-infix class which sets a width of 180px on the input.
Solution: Add the class below to the styles.css file
.mat-form-field-infix {
width: auto!important;
}
StackBlitz: here
I'm developing an Ionic app, and having trouble with my header component. Its elements are wrapping with small screen sizes, and I would like them not to.
Here's the goal:
Here's what's happening now:
I know I could set a fixed width to the header, but I would like not to. I also wouldn't like to use JavaScript to calculate the width.
Here's the HTML/Angular/Ionic code for the title component:
<h1 *ngIf="backButton; else titleBackButton">{{ title }}</h1> <!-- show if backButton != true -->
<ng-template #titleBackButton> <!-- show if backButton == true -->
<button ion-button round class="button-back">
<ion-icon name="arrow-back"></ion-icon>
</button>
<h1 class="floated-title">{{ title }}</h1> <!-- this has been floated to the right -->
</ng-template>
Here are my CSS styles:
.button-back {
margin: 17px 0 0 10px;
}
.floated-title {
float: right;
}
Any time you want to force elements to line-up in a row, and never wrap, give the parent container display: flex. This automatically applies flex-wrap: nowrap and flex-direction: row.
The above suggestion applies to plain CSS. Some frameworks may set different defaults.
For instance, in React, flex-direction defaults to column.
Alternatively, you can apply white-space: nowrap to the container, which suppresses all line breaks inside the container.