Angular2 material team recently released the MDDialog https://github.com/angular/material2/blob/master/src/lib/dialog/README.md
I'd like to change the looking and feel about the angular2 material's dialog. For example, to change the fixed size of the popup container and make it scrollable, change the background color, so forth. What's the best way to do so? Is there a css that I can play with?
There are two ways which we can use to change size of your MatDialog component in angular material
1) From Outside Component Which Call Dialog Component
import { MatDialog, MatDialogConfig, MatDialogRef } from '#angular/material';
dialogRef: MatDialogRef <any> ;
constructor(public dialog: MatDialog) { }
openDialog() {
this.dialogRef = this.dialog.open(TestTemplateComponent, {
height: '40%',
width: '60%'
});
this.dialogRef.afterClosed().subscribe(result => {
this.dialogRef = null;
});
}
2) From Inside Dialog Component. dynamically change its size
import { MatDialog, MatDialogConfig, MatDialogRef } from '#angular/material';
constructor(public dialogRef: MatDialogRef<any>) { }
ngOnInit() {
this.dialogRef.updateSize('80%', '80%');
}
use updateSize() in any function in dialog component. it will change dialog size automatically.
for more information check this link https://material.angular.io/components/component/dialog
Content in md-dialog-content is automatically scrollable.
You can manually set the size in the call to MdDialog.open
let dialogRef = dialog.open(MyComponent, {
height: '400px',
width: '600px',
});
Further documentation / examples for scrolling and sizing:
https://material.angular.io/components/dialog/overview
Some colors should be determined by your theme. See here for theming docs:
https://material.angular.io/guide/theming
If you want to override colors and such, use Elmer's technique of just adding the appropriate css.
Note that you must have the HTML 5 <!DOCTYPE html> on your page for the size of your dialog to fit the contents correctly ( https://github.com/angular/material2/issues/2351 )
With current version of Angular Material (6.4.7) you can use a custom class:
let dialogRef = dialog.open(UserProfileComponent, {
panelClass: 'my-class'
});
Now put your class somewhere global (haven't been able to make this work elsewhere), e.g. in styles.css:
.my-class .mat-dialog-container{
height: 400px;
width: 600px;
border-radius: 10px;
background: lightcyan;
color: #039be5;
}
Done!
You can inspect the dialog element with dev tools and see what classes are applied on mdDialog.
For example, .md-dialog-container is the main classe of the MDDialog and has padding: 24px
you can create a custom CSS to overwrite whatever you want
.md-dialog-container {
background-color: #000;
width: 250px;
height: 250px
}
In my opinion this is not a good option and probably goes against Material guide but since it doesn't have all features it has in its previous version, you should do what you think is best for you.
sharing the latest on mat-dialog
two ways of achieving this...
1) either you set the width and height during the open
e.g.
let dialogRef = dialog.open(NwasNtdSelectorComponent, {
data: {
title: "NWAS NTD"
},
width: '600px',
height: '600px',
panelClass: 'epsSelectorPanel'
});
or
2) use the panelClass and style it accordingly.
1) is easiest but 2) is better and more configurable.
For the most recent version of Angular as of this post, it seems you must first create a MatDialogConfig object and pass it as a second parameter to dialog.open() because Typescript expects the second parameter to be of type MatDialogConfig.
const matDialogConfig = new MatDialogConfig();
matDialogConfig.width = "600px";
matDialogConfig.height = "480px";
this.dialog.open(MyDialogComponent, matDialogConfig);
dialog-component.css
This code works perfectly for me, other solutions don't work.
Use the ::ng-deep shadow-piercing descendant combinator to force a style down through the child component tree into all the child component views. The ::ng-deep combinator works to any depth of nested components, and it applies to both the view children and content children of the component.
::ng-deep .mat-dialog-container {
height: 400px !important;
width: 400px !important;
}
I think you need to use /deep/, because your CSS may not see your modal class. For example, if you want to customize .modal-dialog
/deep/.modal-dialog {
width: 75% !important;
}
But this code will modify all your modal-windows, better solution will be
:host {
/deep/.modal-dialog {
width: 75% !important;
}
}
This worked for me:
dialogRef.updateSize("300px", "300px");
You can also let angular material solve the size itself depending on the content.
This means you don't have to cloud your TS files with sizes that depend on your UI. You can keep these in the HTML/CSS.
my-dialog.html
<div class="myContent">
<h1 mat-dialog-title fxLayoutAlign="center">Your title</h1>
<form [formGroup]="myForm" fxLayout="column">
<div mat-dialog-content>
</div mat-dialog-content>
</form>
</div>
my-dialog.scss
.myContent {
width: 300px;
height: 150px;
}
my-component.ts
const myInfo = {};
this.dialog.open(MyDialogComponent, { data: myInfo });
On smaller screen's like laptop the dialog will shrink. To auto-fix, try the following option
http://answersicouldntfindanywhereelse.blogspot.com/2018/05/angular-material-full-size-dialog-on.html
Additional Reading
https://material.angular.io/cdk/layout/overview
Thanks to the solution in answersicouldntfindanywhereelse (2nd para).
it worked for me.
Following is needed
import { Breakpoints, BreakpointObserver } from '#angular/cdk/layout'
component.ts
const dialog = matDialog.open(DialogComponent, {
data: {
panelClass: 'custom-dialog-container',
autoFocus: false,
},
});
styles.scss
// mobile portrait:
#media (orientation: portrait) and (max-width: 599px) {
// DIALOG:
// width:
.cdk-overlay-pane {
max-width: 100vw !important;
}
// padding
.custom-dialog-container .mat-dialog-container {
padding: 5px !important;
}
}
Related
I am trying to test a border to have display:none when the window is resized.
I am using jest and react-testing-library for this purpose.
I have these simple css rules for my border class
.built-with .border{
position: absolute;
justify-self: center;
height: 50%;
border-left: 1px solid black;
opacity: 0.5;
}
#media (max-width: 590px){
.built-with .border{
display: none;
}
}
I am trying to assert that when window.innerWidth goes less than 500, then .border's display should be none.
Here what I am trying to do:
import {render} from '#testing-library/react';
it("should have styles on different viewports", () => {
const { container } = render(<Footer />);
const border = container.querySelector('.border');
const style1 = window.getComputedStyle(border);
window = { ...window, innerWidth: 500, innerHeight: 700 };
console.log(window.innerWidth); // 500
const style2 = window.getComputedStyle(border);
expect(style1.display).not.toMatch(style2.display);
/*expected - to not match
during test - it matches
*/
});
Here : style1 has a default window.innerWidth of 1024 and style2 has a window.innerWidth
It seems that stylesheets are not rendered in the jsDOM.
Kent (Author of Testing Library) has discussed this issue here
That's why a real browser-like enviroment is necessary to test CSS styles.
Testing css styles during End-to-End tests might be the best possible way.
However, there are some ways to test css-in-js libraries or styled components.
I am having trouble removing these huge white margins on my react project. Below are some of the solutions I have tried.
* { margin: 0; padding: 0; }
/-/-/-/
body {
max-width: 2040px;
margin: 0 auto;
padding: 0 5%;
clear: both;
}
I have tried every variation. My only installed dependencies that should affect anything CSS wise is bootstrap and I don't think thats it. I tried adjusting max-width to a value of 2040px just to test if it would work and there appears to be a limit to which I can set the width. Help would be appreciated.
I should also mention that this is persistent throughout the entire page. This issue is not limited to the background image which I am linking in the css file
White Margins
All the browsers uses different default margins, which causing sites look different in the other browser.
The * is wildcard, means all elements present in our site (consider as universal selector), so we are setting each and every element in our site to have zero margin, and zero padding, to make the site look the same in every browsers.
If your style not getting applied then you can use !important to override style,
* {
margin: 0 !important;
padding: 0 !important;
}
If you created it using create-react-app there will probably be a file public/index.html.
There is a tag wrapped around the root where React will inject you App.
Usually the browser style-sheet set the margin of <body> to 8px.
That's most likely that white margin around your App that you're struggling to get rid off.
To remove it, one option is to open public/index.html and set the margin to 0 using inline styles like this:
<body style=margin:0>
In case you're using #emotion/react for styling you may alternatively (still assuming that there is this body tag in public/index.html) leave it as <body> and use the <Global> component to define styles for <body>. Something like this in your App.js:
function App() {
return (
<div>
<Global
styles={css`
body {
margin: 0;
}
`}
/>
<Your />
<Other />
<Components />
</div>
);
}
export default App;
User agent style sheet overrides the custom style. You can override this using !important in normal html and css
It is better to user react spacing library, rather than overriding the user default style sheet https://material-ui.com/system/spacing/
or you can use the following
<body id="body">
<div id="appRoot"></div>
</body>
style sheet
body
margin: 0
padding: 0
button
padding: 10px 20px
border-radius: 5px
outline: none
React JS code blocks
class A extends React.Component{
componentWillMount(){
document.getElementById('body').className='darktheme'
}
componentWillUnmount(){
document.getElementById('body').className=''
}
render(){
return (
<div> Component A </div>
)
}
}
class App extends React.Component{
constructor(){
super()
this.state = {
isAMount: false
}
}
handleClick(){
this.setState({
isAMount: !this.state.isAMount
})
}
render(){
return (
<div>
<button onClick={this.handleClick.bind(this)}> Click Me</button>
<div> App </div>
<hr />
<div> {this.state.isAMount && <A /> } </div>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('appRoot'))
If you try:
* {
margin: 0 !important;
padding: 0 !important;}
You may have some issues. As I was using some mui, so this was distorting my components. I may recomend to modify the "body" in public/index.html using:
<body style=margin:0>
As you are using background image. Its problem due to image size ratio.
You have to use background-size: cover property in css.
Also use appropriate background-position to make sure the gavel comes in center bottom of page.
I was trying to add a background image in my react app but react left some margin on top and left.
const useStyles = makeStyles((theme) => ({
background: {
backgroundImage: `url(${Image})`,
backgroundPosition: 'center',
backgroundSize: 'cover',
backgroundRepeat: 'no-repeat',
width: '100vw',
height: '95vh',
}
After reading the documentation, I realized that it was not margin, but positioning of the image. Setting the position:fixed with top:0 and left:0 fixed the issue.
After reading the answers above and trying them I have concluded that the best way is to keep your index.css(note: that the index.css in particular has the margins already set to 0 globally.) and App.css files that are auto generated when you "npx create-react-app".
I have noticed that many beginner tutorials tell you to remove these files and more, but after facing this problem it is honestly easier to just edit the boilerplate than start from scratch.
Simply add to the app.css or your main CSS file
body { margin: 0; padding: 0; }
* { margin: 0; padding: 0; } override by browser.
try
html,body{
margin:0;
padding:0;
}
I want my loadingController wrapper to be shown with a customized css style but the css's rules doesn't apply to the element (the loadingController wrapper).
I have this in my component:
ionViewDidLoad() {
let loader = this.loadingController.create({
spinner: 'bubbles',
content: 'getting data...',
cssClass: 'loadingwrapper'
});
loader.present().then(() => {
//some stuff
...
loader.dismiss();
});
}
and this in my css file:
.loadingwrapper{
width: 77% !important;
height: 15% !important;
color: black !important;
font-size: 1.25em !important;
background-color: aliceblue !important;
border-radius: 10px !important;
}
In spite of doing this (I've even tried whithout "!important"), the changes (none of them) doesn't apply to the loading wrapper and it shows a bit awful.
Not sure where you are applying the css but if you are applying the css in the page component file you going to have a hard time, because the loading controller sits outside the page selector. So if your page component name is Foobar and you have a .scss file foobar.scss
page-foobar{
.loadingwrapper{
// not going to work
}
}
you can either add it globally to your app/app.scss file or ( i think this will work )
.md,.ios,.wp{
page-foobar{
.loadingwrapper{
// styles!
}
}
}
You have to do it globally inside the variables.scss file.
Android
$loading-md-border-radius:10px;
ios
$loading-ios-border-radius: 10px
Windows
$loading-wp-border-radius: 10px
You can see global variable list here.
Hi I am trying to build a angular single page app for mobile that uses a map on one page. It also should include a sticky footer, and is based on bootstrap. The sticky footer css interferes with the css needed to get the map to take up all of the remaining screen space, so I add a class='map' to the html element to override certain css elements (see below).
Everything works nicely until I go to the map page, leave it and then return to the map page. In this instance the map is not working correctly at all. It is hard to describe, so please try the plnkr.
I have found CSS that works for the map reloading, but then that breaks something else in the site. It is driving me crazy trying to combine the two models, hence my appeal for help.
Update: I have now found that resizing the screen rectifies the rendering issues, until you leave and return to the map. Of course a mobile use cannot change their screen size, but this may help find a solution.
html {
position: relative;
min-height: 100%;
}
html.map {
height: 100%
}
body {
/* Margin bottom by footer height */
margin-bottom: 60px;
}
.map body {
/* For Google map */
height: 100%;
margin-bottom: 0;
padding-bottom: 60px;
padding-top: 60px
}
footer {
position: absolute;
bottom: 0;
width: 100%;
/* Set the fixed height of the footer here */
height: 60px;
background-color: #f5f5f5;
}
header {
width: 100%;
background-color: #ccc;
height: 60px;
top: 0;
}
.map header {
position: absolute;
}
UPDATE
I implemented a solution similar to yours, which I found in this blog article. Essentially, you have to trigger a resize event in order to have the map repainted correctly when it goes from hidden to visible.
But I put my code into a directive instead of a controller (doesn't bloat controller and decorates the element it affects), instead of adding a watcher it runs only after the directive/element is linked (more performant), and it doesn't require you to re-enter your coordinates in order to refresh:
.directive('autoRefresh', function($timeout){
return {
restrict: 'A',
link: function(scope, elem, attrs){
$timeout(function(){
var center = scope.map.getCenter();
google.maps.event.trigger(scope.map, "resize");
scope.map.setCenter(center);
});
}
}
})
Updated Plunker
OK, so what I was missing was to trigger the resize event. This now works perfectly in my plunker but not yet in my more complex actual code. Nearly there!
restosApp.controller('mapCtrl', function($scope) {
$scope.$watch('map', function() {
google.maps.event.trigger($scope.map, 'resize');
var ll = new google.maps.LatLng(52.374, 4.899);
$scope.map.setCenter(ll);
});
});
So my website can resize based on screen size, but when I implemented a Twitter widget, when I tried resizing it, the widget, despite having the attribute width:'auto' did not resize. Here is the code for the widget:
<script charset="utf-8" src="http://widgets.twimg.com/j/2/widget.js"></script>
<script>
new TWTR.Widget({
version: 2,
type: 'profile',
rpp: 2,
interval: 30000,
width: 'auto',
height: 100,
theme: {
shell: {
background: '#dbdbdb',
color: '#000000'
},
tweets: {
background: '#dbdbdb',
color: '#000000',
links: '#000000'
}
},
features: {
scrollbar: true,
loop: false,
live: false,
behavior: 'all'
}
}).render().setUser('jackstonedev').start();
</script>
And here is the CSS for the widget:
#twittercontainer
{
border:3px solid;
border-radius:20px;
background-color:lightgrey;
opacity:0.7;
max-width:500px;
margin: auto;
}
Annoyingly you can't do this with the new twitter widgets and the old API is due to be binned in march 2013 but I wrote some stuff on how to solve it using the new widgets here using jquery albeit a fairly simplistic approach:
http://tappetyclick.com/blog/2012/12/20/how-dynamically-resize-new-twitter-widget
Try resizing by using % instead of auto.
If the parent div then resizes your widget should aswel, for example if you set your widgets css to
#widget { width: 90%; }
if the parent div is 100 pixels wide, your widget will be 90 pixels wide.
I Hope this works for you.
What might also be a problem is that if the twitter widget is loaded via iFrame / or JS generated, it might assign CSS values aswel, these can override your own set values since they are set when/after the page is loaded. Try inspecting the widget itself in the HTML source and see what is happening to it.
put widget in wrapper and change width to
width: '100%',
it should work as you expect.
I was able to change the width of two widgets to 100% in my Rails application by adding the following code in my stylesheet:
#twitter-widget-0, #twitter-widget-1 {
float: none;
width: 100% !important;
}
I used this:
$('#twitter-widget-0').height($('#ID_SIMILAR HEIGHT').height());