Make Material-UI Reactjs FloatingActionButton float - html

After trying to find an example where the FloatingActionButton floats at its standard bottom-right screen position with no results, I come to you if you could provide one because it seems to be a normal button without floating to that corner by default.
Am I supposed to make it float by setting custom CSS rules?
Material-UI docs doesn't mention any property about floating Material-UI FloatingActionButton documentation.

Indeed, no property for this in the component FloatingActionButton for the moment.
Waiting for it :
1) A solution using inline styles :
At the top of your component, add :
const style = {
margin: 0,
top: 'auto',
right: 20,
bottom: 20,
left: 'auto',
position: 'fixed',
};
... and in your render method :
render() {
return <FloatingActionButton style={style}><ContentAdd /></FloatingActionButton>
}
OR
2) A solution using CSS file
Add in your CSS file (ex : styles.css referenced on your index.html) :
.fab {
margin: 0px;
top: auto;
right: 20px;
bottom: 20px;
left: auto;
position: fixed;
};
... and put on your React component :
render() {
return <FloatingActionButton className="fab"><ContentAdd /></FloatingActionButton>
}

I actually found this on the Material-UI documentation. I just made a few tweaks to it. Here's the resulting code.
import { makeStyles } from '#material-ui/core/styles';
import Fab from '#material-ui/core/Fab';
import AddIcon from '#material-ui/icons/Add';
const useStyles = makeStyles(theme => ({
fab: {
position: 'fixed',
bottom: theme.spacing(2),
right: theme.spacing(2),
},
}));
add this to your component
const classes = useStyles();
return (
<Fab color="primary" aria-label="add" className={classes.fab}>
<AddIcon />
</Fab>
);

If you want to manipulate CSS in material-ui, its better to use withStyles currying function.
Like this:
import React, {Component} from 'react';
import {Button} from "material-ui";
import {Add} from 'material-ui-icons';
import { withStyles } from 'material-ui/styles';
const style = theme => ({
fab: {
margin: 0,
top: 'auto',
left: 20,
bottom: 20,
right: 'auto',
position: 'fixed',
}
});
class MyPage extends Component{
render() {
const {classes} = this.props;
return <Button fab variant="fab" color="primary" aria-label="add" className={classes.fab}><Add />
</Button>
}
export default withStyles(style)(MyPage);
Documentation link: https://material-ui.com/customization/css-in-js/

In MUI v5, you can add the one-off styles directly to the Fab component via the sx props. Set the position to fixed (as opposed to absolute in other answers*) along with the anchor positions and you're done.
return (
<Fab
sx={{
position: "fixed",
bottom: (theme) => theme.spacing(2),
right: (theme) => theme.spacing(2)
}}
color="primary"
>
<AddIcon />
</Fab>
);
*: Setting to absolute will anchor the button to the bottom right of the closest relative container, the container itself will be moved if the user scrolls down which in turn moves the button. Use fixed value to anchor the button in relative to the viewport, so the scrolling would not affect the button position.

If you are creating a custom theme you can use the theme overrides to style the FAB (Floating Action Button) is floating in the bottom right corner:
import { createMuiTheme } from "#material-ui/core";
export default createMuiTheme({
overrides: {
MuiFab: {
root: {
position: 'absolute',
bottom: '2rem',
right: '2rem'
}
}
}
});
This will override the FAB for every component usage. You can use the same style with a specific class name and override it again for other usages.

In case of custom theme, in MUI v5 the overriding of the style it's a bit different from the v4,
see MUI v5-style-changes.
components: {
MuiFab: {
styleOverrides: {
root: {
position: 'fixed',
bottom: '2rem',
right: '2rem'
}
}
}
}

Related

Modify default classes of DataGrid material UI

In "DataGrid" material UI I am trying to modify the css properties like font weight, overflow of header.
Here is my jsx code
import React, {useState, useEffect} from 'react';
import {DataGrid, GridToolbarContainer, GridToolbarExport} from '#material- ui/data-grid';
import {makeStyles} from '#material-ui/styles';
const useStyles = makeStyles({
root: {
'& .super-app-theme--header': {
backgroundColor: 'white'
}
},
'.MuiDataGrid-root .MuiDataGrid-columnHeaderTitle': {
fontWeight: 'bold',
overFlow: 'visible'
}
});
function CustomToolbar() {
return (
<GridToolbarContainer>
<GridToolbarExport />
</GridToolbarContainer>
);
}
export default function DataTable(props) {
const classes = useStyles();
return (
<div style={{height: '700px', width: '100%'}} className={classes.root}>
<DataGrid
rows={props.records}
columns={props.headers}
pageSize={12}
components={{
Toolbar: CustomToolbar
}}
/>
</div>
);
}
I also tried to add properties like font weight and overflow in super-app-theme--header but it didn't work. Some properties like background colour are working but the properties which are already there in MuiDataGrid-columnHeaderTitle are not getting overridden.
I created a css file and in that overridden the properties with same class name and imported that css file
Here is the css code
.MuiDataGrid-columnHeaderTitle { font-weight: bold !important; overflow: visible !important; }
Using MUI V5+ and building on Pravin's answer you can define the header style this way:
<Datagrid
sx={{
'.MuiDataGrid-columnHeaderTitle': {
fontWeight: 'bold !important',
overflow: 'visible !important'
}
}}
/>

Angular Css not being executed from angular component css

My angular project is reading from a library that contains this code is a class:
class MyClass extends EventEmitter {
constructor () {
// add the element to the container
this.loadingElement = document.createElement('div');
this.loadingElement.className = "loading"
this.loadingElement.innerText = 'Now Loading...';
}
}
In my app.component.css I have this:
#componentDivId .loading {
position: absolute;
top: 50%;
left: 50%;
}
This css is in app.component.css
How can I change this so it reads the css?
You should look into ::ng-deep for overriding component styling. Also, may need to use !important in css file as and when required
Here is a demo code to help you understand how ::ng-deep can be used to push styling to a child component.

Override material-ui button styles with styled-components

I am using a material-ui button and trying to override the border-radius (i.e, make it 0) through styled-components. However, it's not working.
Code:
import React from "react";
import styled from "styled-components";
import { Button } from "#material-ui/core";
const StyledButton = styled(Button)`
background-color: #d29d12;
border-radius: 0;
`;
export default function App() {
return <StyledButton>Hello</StyledButton>;
}
By default, Material-UI injects it styles at the end of the <head> element. This means that its styles will come after styles generated by styled-components and thus the Material-UI styles will win over the styled-components styles when CSS specificity is the same.
You can use the StylesProvider component with the injectFirst property to move the Material-UI styles to the beginning of the <head> and then the styled-components styles will come after it and win.
import React from "react";
import styled from "styled-components";
import Button from "#material-ui/core/Button";
import { StylesProvider } from "#material-ui/core/styles";
const StyledButton = styled(Button)`
background-color: red;
border-radius: 0;
`;
export default function App() {
return (
<StylesProvider injectFirst>
<div className="App">
<StyledButton>Hello</StyledButton>
</div>
</StylesProvider>
);
}
Related answers:
Media Queries in Material-UI Using Styled-Components
Use styled-components higher specificity syntax:
https://styled-components.com/docs/faqs#how-can-i-override-styles-with-higher-specificity
const StyledButton = styled(Button)`
&& {
background-color: red;
border-radius: 0;
}
`;
const StyledButton = styled(Button)({
'&&&': {
backgroundColor: red,
borderRadius: 0
}
)}
By adding className to StyledButton, it can override MUI button style,
<StyledButton className={'myclassName'}>Hello</styledButton>
const StyledButton = styled(Button)`
&.myclassName {
background-color: red,
border-radius: 0
}
`;
You can override the default border-radius of button by applying !important to your styled component.
const StyledButton = styled(Button)`
borderRadius: 0px !important;
`;

Blurring the contents in a div when Modal is displayed?

I have an side-drawer/modal that will slide into view when clicking on an image of my application. I'm trying to blur all the contents behind the side-drawer when it comes into view, I realized I might need another component like Backdrop that takes the whole content of the page and somehow blur the whole div when the side-drawer is displayed.
I tried using backdrop-filter but that's not supported in Chrome yet. Are there any alternatives? Or am I going to need a transparent "dummy" image to blur?
My component is just this:
import React from 'react';
import styles from './styles.module.css';
const backdrop = props => (
<div className={styles.backdrop} onClick={props.click}></div>
)
export default backdrop;
I tried this:
.backdrop {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
filter: blur(2px);
z-index: 300;
}
And mounting it on my app as so:
class App extends Component {
componentDidMount() {
const { loadUserAction } = this.props;
const {
auth: { token }
} = readLocalStorage();
if (token) loadUserAction(token);
}
render() {
return (
<BrowserRouter>
<Route exact path={signInPath} component={Login} />
<Backdrop />
<SideDrawer />
<ProtectedRoute exact path={feedPath} component={MovieFeed} />
</BrowserRouter>
);
}
}

Is it possible to have sticky div inside an angular form?

I'm working with angular and angular-material.
Inside a page, I have a form, and some buttons (grouped in a div) which are depending on this form.
But, I'd like to have these buttons (the div) sticking the bottom of the page, even if I scroll.
Here's some code :
<form (ngSubmit)="update()" #updateForm="ngForm">
<div> some content with inputs and selects </div>
<div class="button-container"> buttons like save, cancel, ... </div>
</form>
and :
.button-container {
position: sticky !important;
bottom: 0;
float: right;
z-index: 999;
}
If I put the buttons out of the form, they don't work anymore. Thing is, it'd be better if I don't change the buttons' methods, and only modify HTML and CSS.
What I did doesn't work, any idea ?
I did this on plunker, with the same CSS properties as my project https://plnkr.co/edit/pw7zOruWwhV0o1Vya717?p=preview
In case you cannot reproduce the failing version in plunkr, then some other css-styling in your project might be preventing the sticky-position.
In my case the sticky-position did not work in case the containing div had
overflow:hidden;
Maybe you have the value set on the containing div?
I think I had the same problem. Normally I would use position fixed but this wouldn't work because material used transform: translate3d(0,0,0). This made fixed to behave like absolute. To solve this problem I used the below:
//Place this in your form
<app-fnls-displacer>
<div style="position: fixed; right: 30px; bottom: 30px; padding-bottom: 2em; z-index: auto">
<button mat-fab class="fab" type="submit" (click)="myfunction()">
<mat-icon>add</mat-icon>
</button>
</div>
</app-fnls-displacer>
This is the component and directive used:
import {AfterViewInit, Component, Directive, OnDestroy, TemplateRef, ViewChild, ViewContainerRef} from '#angular/core';
import {Overlay, OverlayRef, OverlayConfig, TemplatePortal} from '#angular/material';
#Directive({ selector: '[displacerPortal]' })
export class DisplacerPortalDirective extends TemplatePortal<any> {
constructor(templateRef: TemplateRef<any>, viewContainerRef: ViewContainerRef) {
super(templateRef, viewContainerRef);
}
}
#Component({
selector: 'app-fnls-displacer',
template: `
<ng-template displacerPortal>
<ng-content></ng-content>
</ng-template>
`
})
export class DisplacerComponent implements OnDestroy, AfterViewInit {
private _config = new OverlayConfig();
#ViewChild(DisplacerPortalDirective)
private _portal: DisplacerPortalDirective;
private _overlayRef: OverlayRef = undefined;
constructor(private _overlay: Overlay) {}
public ngOnDestroy() {
this._overlayRef.detach();
}
public ngAfterViewInit() {
this._overlayRef = this._overlay.create(this._config);
this._overlayRef.attach(this._portal);
}
}
I found it on a material GitHub page. It places the content inside it directly to the body, so that you can use position: fixed.
Set a fixed height to the scrolling element and fix the button position:
<div style="height:calc(100vh - 100px) !important; overflow: scroll !important" class="mat-tab-body-content ng-trigger ng-trigger-translateTab">
......
<button style="top: calc(100vh - 50px) !important; position: fixed !important" md-button (click)='alert("clicked!");'>button</button>
Plunker