How to test css styles when window is resized? - css

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.

Related

How to add media breakpoints dynamically in Typescript style components using React Hooks

I need height > width for mobile devices, for that i removed the aspectRatio from index.js in handleResize function inside src/camera folder and somehow it worked. But i feel it's a kindof hacky thing to do. Can any one suggest how can i solve my problem for different media breakpoints.
Below is my sandbox code, which i borrowed from Andrews James's post :
https://blog.logrocket.com/responsive-camera-component-react-hooks/
https://codesandbox.io/s/react-camera-component-s0uqfr
Edit: Specific Problem
const [container, setContainer] = useState({ width: 0, height: 0});
const [aspectRatio, calculateRatio] = useCardRatio(0.586);
function handleResize(contentRect) {
setContainer({
width: contentRect.bounds.width,
height: Math.round(contentRect.bounds.width / aspectRatio)
// height: Math.round(contentRect.bounds.width)
});}
css Style:
export const Container = styled.div`
position: relative;
width: 100%;
max-width: ${({ maxWidth }) => maxWidth && `${maxWidth}px`};
max-height: ${({ maxHeight }) => maxHeight && `${maxHeight}px`};
overflow: hidden;
`;
Now the height property gets fixed regardless of any resolution in chrome devtools dimensions.
Thanks in Advance.
You can use css variables.
document.style.setProperty("--my-breakpoint", myValue);
with that media query
#media(max-width: var(--my-breakpoint)) {
// anything you want
}

make border radius of ionic image in ionic react app

I am making an ionic react app. I can not make border radius of ionic image. Help me to solve the problem.
Here is my code of js file:
import { IonGrid, IonImg } from '#ionic/react';
import './aboutUs.scss';
const AboutUs = () => {
return (
<IonGrid className="about-us">
<IonImg className="about-image" src="https://cutt.ly/MWaU9I0"></IonImg>
</IonGrid>
);
};
export default AboutUs;
Here is my code of scss file:
.about-us{
padding: 1.25em;
.about-image{
border-radius: 5em;
}
}
You most likely want to set it to important, to override ionic defaults, and hide overflow, i.e:
.about-us{
padding: 1.25em;
.about-image{
border-radius: 5em !important;
overflow: hidden;
}
}
According to this duplicate here:
How to add border-radius to ion-img in Ionic 4

styled-components local variable

Coming from SCSS (SASS)
What would be the appropriate Styled-Components implementation of the below SCSS code?
SCSS:
.circle{
$size: 16px; // <-- SCSS FTW. use such a trick in styled-components
height: $size;
width: $size;
.. rest of properties...
}
Currently the styled-component (Circle) looks like this:
...lots of other styled exports
export const Circle = styled.div`
height: 16px;
width: 16px;
background: red;
border-radius: 50%;
`
...lots of other styled exports
Problem is, I want to keep that "meaningless" size variable in the same context where it's consumed (just like in SCSS) because nothing else cares or will ever care about it. I don't think dumping a variable somewhere and then using it with '${size}' is a "clean" way. such tactics are petty and promote messy code-base.
I have devised a neat trick to encapsulate variables only for a specific scope:
styled.h1(({size='4em', color='lime'}) => `
font-size: ${size};
color: ${color};
text-align: center;
`)
I've written a Medium post in the past which breaks down the explenation of this method
One way to solve this problem is to create a separate file with all the variables that you want to use later in your style files:
export const Variables = {
size: '16px',
bgColor: 'red',
}
then you can import it:
import { Variables } from './Variables'
export const Circle = styled.div`
height: ${Variables.size};
width: ${Variables.size};
background: ${Variables.bgColor};
border-radius: 50%;
`
You can use classic css properties (with IE11 polyfill in mind) like this:
--radioWidth: 42px;
.MuiRadio-root {
width: var(--radioWidth);
}
.conditionCollapse {
padding-left: var(--radioWidth);
}

Ionic 2 loadingController cssClass not working

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.

Angular2 Material Dialog css, dialog size

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;
}
}

Resources