Angular Material icon button formatting - css

This question has a Stackblitz demo; Given the following Angular Material button
<button md-button>
<span>Foo</span>
<md-icon>keyboard_arrow_down</md-icon>
</button>
How can I increase the gap between Foo and the icon (see below):
I thought this would be easy but Angular Material wraps the contents in <span class="mat-button-wrapper"> so the final markup is more like:
<button>
<span class="mat-button-wrapper">
<span>Foo</span>
<mat-icon>keyboard_arrow_down</mat-icon>
</span>
</button>
So far I've got as far as adding the following CSS to make the wrapper fill the available space but I can't see how to progress:
.mat-button-wrapper {
display: inline-block;
width: 100%;
}

.mat-button-wrapper > span {
margin-right: 2em;
}
Stackblitz :-
https://stackblitz.com/edit/angular-material-6z4j4m

button md-icon {
margin-left: 64px;
}
This is more semantically appropriate.
https://stackblitz.com/edit/angular-material-yvqvhm

Related

How to Use Css Variable in React Component?

I want to use content variable with in-line styles in react, but I dont know how to do this ?
CSS3
.right::after, button::after {
content: var(--content);
display: block;
position: absolute;
white-space: nowrap;
padding: 40px 40px;
pointer-events:none;
}
React Component
return (
<Button
{...configButton}
style={{'--content': "Login" }}
>
<div class="left"></div>
Login
<div class="right"></div>
{children}
</Button>
);
Ok the solution to this problem is quite simple, It made me think for a while.
The css variable that you provided works indeed.
But when it comes to the content of a psudo element then you should provide the value with a pair of quotes and it will work fine.
<Button
{...configButton}
style={{'--content': "'Login'" }}
>
change the "Login" into "'Login'" and this should work fine.
thank you.
It should work.
Are you passing style to the actual rendered element in Button component?
Is the CSS aplied?
div:after {
content: var(--test-var);
}
<div style="--test-var: 'Test'"></div>

How to write LESS selector that targets buttons not disabled?

index.html:
<div>
<span>
<button disabled>
Button 1
</button>
<button>
Button 2
</button>
</span>
</div>
index.less:
:not(&[disabled]) button {
background-color: red;
}
This gives the below output. Both buttons are colored red but I am trying to target only button that is not disabled.
Is there a way to do this? I am specifically looking to target buttons that are not disabled.
Here is the jsfiddle : https://jsfiddle.net/6gqb19e3/36/
I am new to LESS and my syntax was wrong. After bit of trial and error, I came up with this:
button {
background-color: grey;
&:not([disabled]) {
background-color: green;
}
}
and it gives this output:
Here is the jsfiddle with: https://jsfiddle.net/6gqb19e3/81/

how to terminate hover state on iphone

I have a list of products with icons for contents. When hovering an icon a text explains the meaning of the image.
Because on touchscreens hover doesn't exist, I use :active, too.
My solution works perfect
- on desktop (hovering shows text, moving mouse away: text disappears)
- and on normal phones (touch shows text, touching somewhere else: text disappears
but not on Iphones: touch shows text, but it stays even when touching somewhere else (except when touching another "hoverable" image)
HTML:
<span class="canhover">
<img class="icon24" src="img/allergens/gluten.jpg">
<span class="hovertxt">
contains gluten
</span>
</span>
<span class="canhover">
<img class="icon24" src="img/allergens/milk.jpg">
<span class="hovertxt">
conains milk
</span>
</span>
...
CSS:
.canhover {
position: relative;
}
.canhover:hover .hovertxt, .canhover:active .hovertxt {
display: block;
}
.hovertxt {
display: none;
position: absolute; bottom: 2em; left: 0;
}
How can I achieve that the text also disappears on I phones when toching somewhere else?
Try to add :focus with :hover & :active like this :
.canhover:hover .hovertxt,
.canhover:focus .hovertxt,
.canhover:active .hovertxt{
display: block;
}
and in safari browser use safari prefix

Angular Material Side Bar with "Half" side mode

I am working on the dynamic side bar for our project, basically what we want to do is to set up a dynamic side bar when user click on the side bar it will spread when user click back sidebar should collapse and show only icons (but not totally collapse it will keep the icons) for example before user click the icon. We are using sidenav.toggle()from angular material function which basically closes the sidebar completely and if I don't use toggle() function "Side" mode for navbar does not work. So I want collapse to icon with side mode. (The other reason we need to keep the side mode is that we also need to make sure when user spread the sidebar, right side content should push to right)
After user click the icon
Is there a way to do that?
Thanks.
Option 1: Generating Automatically:
You can create a navigation component from templates provided by Material itself using 'Angular CLI component schematics'
ng generate #angular/material:nav your-component-name
The above command will generate a new component that includes a toolbar with the app name and a responsive side nav based on Material breakpoints.
See more about angular material schematics here
Option 2: Implementing Manually:
To implement that, you just have to refer these two links:
Resizing Sidenav | Angular Material
Navigation List | Angular Material
glance through the following code. Implementation will be something like this:
<mat-drawer-container class="example-container mat-typography" autosize>
<mat-drawer #drawer mode="side" disableClose="true" opened="true">
<button mat-mini-fab (click)="isExpanded = !isExpanded" color="warn" style="margin: 10px;">
<mat-icon aria-label="Menu">menu</mat-icon>
</button>
<mat-nav-list>
<mat-list-item>
<mat-icon mat-list-icon>person</mat-icon>
<h4 mat-line *ngIf="isExpanded">Management A</h4>
</mat-list-item>
<mat-list-item>
<mat-icon mat-list-icon>assignment</mat-icon>
<h4 mat-line *ngIf="isExpanded">Management B</h4>
</mat-list-item>
<mat-list-item>
<mat-icon mat-list-icon>domain</mat-icon>
<h4 mat-line *ngIf="isExpanded">Management C</h4>
</mat-list-item>
<mat-list-item>
<mat-icon mat-list-icon>folder_shared</mat-icon>
<h4 mat-line *ngIf="isExpanded">Management X</h4>
</mat-list-item>
</mat-nav-list>
</mat-drawer>
<div class="example-sidenav-content">
You cards and screen Contents goes here..
Will be pushed towards right on expanding side navbar.
</div>
</mat-drawer-container>
I did this with a bit of CSS
mat-sidenav:not(.mat-drawer-opened) {
transform: translate3d(0, 0, 0) !important;
visibility: visible !important;
width: 60px !important;
overflow: hidden;
}
So when the draw is NOT open, the width of the sidenav is 60px and not 0. Just enough to show your icons.
OK, the next issue is that you'll need to hide a bunch of stuff like button name and other descriptive stuff, for me I need to change the height of the profile image and hide additional text. I did this in the same way as above using the :not selector:
mat-sidenav:not(.mat-drawer-opened) div.leftNav div.navProfile img {
width: 40px; margin: 16px 0 0px 0;
}
mat-sidenav:not(.mat-drawer-opened) .navTitle,
mat-sidenav:not(.mat-drawer-opened) .profileTitle {
display: none;
}
When collapsed I didn't want to show the button names so I wrapped the name in a *ngIf
<span class="navName" *ngIf="opened">{{ page?.name }} </span>
This should work, and it does but there is a problem. The ngIf is bound to the opened event and you will notice a delay when the event is firing (to account for it animation) to show your labels when the drawer is open.
To fix this I had to delve into the api of sidenav and found an eventemitter call openedStart and closedStart. I created a new bool in the component class,
showNavLabels: boolean;
then bound the events to this bool in the HTML.
<mat-sidenav class="sidenav" #sidenav mode="side" [(opened)]="opened"
(openedStart)='showNavLabels = !showNavLabels'
(closedStart)='showNavLabels = !showNavLabels' >
I am sure there is better way as I am not that experienced with Angular yet.
I hope it helps you out.
I created an example based on scss. Maybe someone can help to create the mobile version according to this sample.
Step 1: Add below style to styles.scss
// src/styles.scss
:root {
--menu-width-open: 200px;
--menu-width-closed: 64px;
}
.mat-drawer-container {
.mat-drawer {
box-sizing: content-box;
width: var(--menu-width-open);
transition: all 0.3s ease-in-out !important;
}
.mat-drawer-content {
// transform: translateX(200px);
margin-left: var(--menu-width-open) !important;
transition: all 0.3s ease-in-out !important;
}
&.container-closed {
.mat-drawer {
width: var(--menu-width-closed);
}
.mat-drawer-content {
// transform: translateX(64px) !important;
margin-left: var(--menu-width-closed) !important;
}
}
}
Step 2: Add drawer to app.componenet.html
<mat-drawer-container class="example-container" autosize [ngClass]="{ 'container-closed': !showFiller }">
<mat-drawer #drawer class="example-sidenav" mode="side" disableClose="true" opened="true">
<button (click)="showFiller = !showFiller" mat-raised-button>click</button>
</mat-drawer>
<div class="example-sidenav-content">
<router-outlet></router-outlet>
<button type="button" mat-button (click)="drawer.toggle()">Toggle sidenav</button>
</div>
</mat-drawer-container>
Step 3: And add showFiller = false; to app.component.ts file.
// app.component.ts
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
showFiller = false;
}
There is a feature request for this https://github.com/angular/material2/issues/1728
if you read the comments you'll also find a few examples on how to implement it yourself while it's not officialy available.

Materail Design Lite - How to put inline icon in form

I want put in the same line of the field the face icon. The code is this:
<i class="material-icons">face</i>
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="text" id="sample3">
<label class="mdl-textfield__label" for="sample3">Text...</label>
</div>
and the result is this:
How to put in the same line the icon and the field?
Thanks
Using Email Address / Email Icon as example.
HTML
Add the icon as a child element of the textfield
<div class=
"mdl-textfield mdl-js-textfield mdl-textfield--floating-label is-upgraded"
data-upgraded=",MaterialTextfield">
<input class="mdl-textfield__input" id="textfield-EmailAddress" type=
"email">
<label class="mdl-textfield__label" for=
"textfield-EmailAddress">Email Address</label>
<span class="mdl-textfield__error">Please Enter Valid Email Address</span>
<i class="material-icons mdl-textfield__label__icon">mail</i>
</div>
CSS
.mdl-textfield__label__icon {
position: absolute;
right: 0;
top: 20px;
}
Required Resources
You need to load both the MDL CSS and the Material Design Icons
<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="https://code.getmdl.io/1.1.3/material.indigo-pink.min.css">
MDL JS will help with dynamic behavior
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script defer src="https://code.getmdl.io/1.1.3/material.min.js"> </script>
For Example you can have your icon turn the same 'active' color as your input when focused
.mdl-textfield.is-focused .mdl-textfield__label__icon, .mdl-textfield.is-invalid.is-focused .mdl-textfield__label__icon {
color: rgb(63,81,181);
}
If you want the icon to be left-aligned you could adjust CSS above, but also need to adjust padding on the input to ensure that the input's text does not collide with the icon. Still possible with solution above, but with icon being right aligned its not as likely to happen
There's a solution by Jeremy Fily for left-aligned text-field icons.
The solution also includes js to colour the field and icon according to whether it's selected, but the part that inlines the icon to the left is this css
.mdl-textfield__icon {
width: 32px;
text-align: center;
position: absolute;
line-height: 1.5;
}
.mdl-textfield__icon ~ * {
margin-left: 48px;
width: calc(100% - 48px);
}

Resources