React responsive navbar between state and media query - reactjs

i have a sidebar that will disappear on a width of 992px and below using the following media query :
#media only screen and (max-width: 992px) {
.sideBar {
display: none;
}
}
while mobile nav icon also appear through the following code:
<nav class="mobileNav">
<div class="navLink" href="#">
<div></div>
<div></div>
<div></div>
</div>
</nav>
#media only screen and (max-width: 992px) {
.mobileNav {
display: flex;
}
}
now when i click on this nav , sidebar should appear and disappear, so i made the following state :
const [showSidebar, setShowSidebar] = useState(true);
and modified the following code :
{showSidebar ? (
<div className="sideBar">
<SidebarComponent />
</div>
) : null}
and added onClick function to modify the state :
<nav class="mobileNav" onClick={() => setState(!state)>
...
</nav>
when user clicks on nav element, it indeed changes the state, but sidebar will not appear because of the css media query :
#media only screen and (max-width: 992px) {
.sideBar {
display: none;
}
}
so how can i make the state override the media query, or how to solve it in a better way ?

You should aim to use either CSS OR JS for your solution rather than both.
So you can have the sidebar always in the DOM but use CSS to hide/move it off screen and then all the control is in the CSS.
Or you can hide and reveal the sidebar/nav in JS based on screen/window width but this will require you create an event listener so that every time the user adjusts the windows size you check again if you should hide or reveal the sidebar/nav.
Also instead of using your media query on ".sidebar" add an additional class such as "sidebar--active" or similar and then use JS to add/remove the classname as needed and the css to hide or reveal it.

Related

How to add full page background image in NextJS

I'm trying to add a background image to an entire welcome page in NextJS and it's just not working. Before, I was having trouble with the fact that NextJS seems to render every component inside a master component that becomes an html div with a class of "__next". Therefore, every time I try and add a background image that takes the full page, it is only as big as the "__next" div and is cut off. I tried using NextJS' image component, but now it doesn't even load the image and just displays the alt text. Can anyone tell me how to fix the following code?
import React from "react";
import styles from "/styles/WelcomePage.module.css";
import Card from "/Components/Card";
import Link from "next/link";
import Image from "next/image";
function WelcomePage() {
return (
<>
<Card>
<h1 className={styles.title}>Welcome to Class Chooser</h1>
<button type="button">
<Link href="/ClassSearch"> Class Search </Link>
</button>
<Image
src="/images/graduates.jpg"
alt="Cartoon graduates jump with happiness"
quality="100"
layout="fill"
/>
</Card>
</>
);
}
export default WelcomePage;
To add a background image simply do it via CSS:
.card {
background-image: url("/images/graduates.jpg");
}
make your parent component (Card) position relative and add below properties to next-image.
layout="fill"
objectFit="cover"
position relative should be there for which you need to apply image as a background.
When you add layout="fill" to Image you need to wraper Image component in parent element and assing postion property to parent (relative, absolute, ...).
Wrap your Image inside a parent div, and make your parent position fixed
<div className="bg-image-wrapper">
<Image
src="/images/graduates.jpg"
alt="Cartoon graduates jump with happiness"
quality="100"
layout="fill"
/>
</div>
In css
.bg-image-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
}

How to remove menubar-button in PrimeReact's MenuBar?

I want a MenuBar with no hamburger button appearing while in responsive mode. I'm using CSS module to style my components. How can I completely remove hamburger menu button using CSS module? I can't find a way to access its specific HTML tag <a class="p-menubar-button" ...> and do Display: None.
MenuBar declaration in NavBar.js -
import { Menubar } from 'primereact/menubar'
import styles from './NavBar.module.css'
const NavBar = () => {
return (
<Menubar start={start} end={end} className={styles.menubar} />
)
}
CSS in NavBar.module.css -
.menubar {
// I don't know how to access .p-menubar-button here
}
MenuBar component in plain HTML -
<div class="p-menubar p-component NavBar_menubar__ZntdZ">
<div class="p-menubar-start">...</div>
<a class="p-menubar-button" ...>...</a>
<div class="p-menubar-end">...</div>
</div>
Turns out, it is easy to solve using CSS's child selector and attribute selector. I didn't know those selectors work with CSS module.
Here is the solution in NavBar.module.css -
.menubar > a[class="p-menubar-button"] {
display: none !important;
}

I want to use RTL, but not through all of my components

I want to use RTL for some of my components in Nextjs. I also use material-ui. Unfortunately when I change direction in _documents.js with <HTML dir="rtl">, the direction of all of my components will change. material-ui's direction in createMuiTheme() doesn't affect direction at all.
Some of the components (like arrows) must not change based on direction. What should I do in order to keep them safe from changing direction.
Material Ui createMuiTheme get direction as an option itself
I also remember that it respect the direction of body tag
So for changing the direction of some part of your component, you have 3 ways as I know.
Change direction option in material createMuiTheme
It could be handle via your theme provider component for example
Use other instance of material Theme provider around your rtl components
Theme nesting
Put dir="rtl" on native DOM tags these will affect all lower subtree styles if you want e.g. flex-box direction and ...
for example
const ARABIC_PATTERN = /[\u0600-\u06FF]/
const getDirection = text => (ARABIC_PATTERN.test(text) ? 'rtl' : 'ltr')
<div dir={getDirection('what you want to test')}>
<Components />
</div>
Hacky suggestion. It's probably not the best answer, but it might be handy/decent if you need to just "reset" the position of 1-2 elements.
First invert everything like your are doing, then put a CSS class on the elements that shall not be "inverted":
.not-rtl-inteverted {
transform: scaleX(-1);
}
This way, you are basically inverting everything, and then inverting once again the elements with the class above.
section {
display: flex;
justify-content: space-around;
}
div {
background: green;
padding: 20px;
margin: 0 10px;
flex-basis: 33%;
}
.rtl {
transform: scaleX(-1);
}
<section>
<div>
<p>No RTL</p>
</div>
<div>
<p>Yes RTL</p>
</div>
<div>
<p>Yes RTL - but reset it on the 2nd line (by applying the same CSS class again)</p>
</div>
</section>
<section>
<div>
<p>text 1</p>
<p>text 2</p>
</div>
<div class="rtl">
<p>text 1</p>
<p>text 2</p>
</div>
<div class="rtl">
<p>text 1</p>
<p class="rtl">text 2</p>
</div>
</section>
In the example, by using twice the same class (once in the parent and once again the children that doesn't need to be rtl'd, we have this reset effect).
Again, might be handy for very simple use cases. I won't suggest this as a general solution to your problem.

React material-table: How can I override the style of title in material-table?

I am using material-table "https://material-table.com/"
This is my component that renders a table of data. Here, I am using a custom button inside title for adding new data. It is inside title so that the button goes on the top-left side. I am not using the default add option given by material-table because I want to display a separate form page for adding data instead of inline-adding given by material-table. It works perfectly.
The problem is that the default styling of title has overflow:hidden which can be seen by inspecting it.
<div class='MTableToolbar-title-35'> .... </div>
I want this overflow:hidden to be overflow:auto. How can I override the styling of this title?
export const EmployeeView = ({columns,data}) => {
return (
<div>
<MaterialTable
columns={columns}
data={data}
title={
<div>
<IconButton size='small' color='primary' onClick={() => console.log("Add employee")}>
<AddCircleIcon />
</IconButton>
</div>
}
onRowClick={(event,rowData) => console.log(rowData)}
/>
</div>
)
}
Please use this in the css file
.MuiTypography-h6{
font-size: 1rem;
color: red;
overflow:auto
}
I mentioned the color and font size for testing.

react styling web page with map function

Would it be possible for someone to tell me how to put as many folders (icons) and text as possible below each folder in a row.
At the moment the one folders and text are displayed are displayed on each row. I would like to be able to display 5 folders all on the same row.
Thanks.
render() {
return (<div>
{this.state.Folder.map((item, index) => {
return (<div >
<FontAwesome name={"fas fa-folder fa-3x"} />
<h2> {item.FolderName}</h2>
</div>
);
})}
</div>)
In the wrapper div you could add style/class to display grid, then set the column number to be 5.
Here's an example for the class:
.wrapper {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-gap: 10px;
}
More details at MDN here.

Resources