How to change CSS of a child component from parent component - css

I have a react component called TeamBanner like so
import styles from "./teamBanner.module.css";
import { useNavigate } from "react-router-dom";
import { TeamBannerProps } from "../ProjectTypes.types";
export const TeamBanner = ({
team,
onBannerClick,
showName,
}: TeamBannerProps) => {
let navigate = useNavigate();
const handleOnClick = () => {
navigate(`/${team}`);
onBannerClick();
};
return (
<div
className={`${styles.container} flex theme-light ${
showName ? "" : styles["no-name"]
}`}
title={team}
onClick={handleOnClick}
>
<div>
<img
src={require(`../logos/${team}.svg`)}
alt="logo"
className={`${styles.logo} ${showName ? "" : styles["only-logo"]}`}
/>
</div>
{showName ? team : ""}
</div>
);
};
The teamBanner.module.css file is like so
.container {
margin: 0.25em;
align-items: center;
cursor: pointer;
top: 0;
z-index: 2;
background-color: hsl(var(--color-background));
padding: 0.1em 0.25em;
border-radius: 0.5em;
box-shadow: 0.05rem 0.05rem 0.2rem rgb(0 0 0 / 50%);
font-family: var(--ff-serif);
font-size: var(--fs-200);
}
.logo {
display: inline-block;
vertical-align: middle;
width: 3vmax;
height: 3vmax;
}
.container:hover {
outline: 0.15em solid hsl(240, 90%, 67%);
}
.no-name {
border-radius: 0.25em;
}
.only-logo {
width: 5vmax;
height: 5vmax;
}
I am using it to create a list of team of a page & this works just fine.
However, I want to use it in another place also. In the place, the to now want the .container:hover effect & I want the font properties of the .contaner and width & height properties of the .logo changed.
How can I accomplish this? only changing these items of the module.css? Can any one help? Thanks

Related

How to style VideoJS with Next.js

I am building a react video component based on VideoJS and I used to style VideoJS player using a stylesheet of mine but since I import it as recommended by Next.js documentation, some class targeting seem not to work properly and my custom CSS does not apply to .video-js css components.
This works:
.video {
font-family: 'Inter', -apple-system, Helvetica;
font-weight: bold;
}
.video *:before {
text-shadow: 1px 1px 7px rgba(10, 10, 10, 0.5);
}
This doesn't work:
/* Big play button */
.video .vjs-big-play-button {
height: 2em;
width: 2em;
font-size: 5em;
line-height: 2em;
border: none !important;
border-radius: 9999px;
}
My VideoPlayer component:
import { useCallback, useEffect, useState } from 'react';
import videojs from 'video.js';
import 'video.js/dist/video-js.css'
import styles from '../styles/video-player.module.css';
function VideoPlayer(props) {
const [videoEl, setVideoEl] = useState(null);
const onVideo = useCallback((el) => {
setVideoEl(el)
}, [])
useEffect(() => {
if (videoEl == null) return
const player = videojs(videoEl, props)
return () => {
player.dispose()
}
}, [props, videoEl])
return (
<div data-vjs-player>
<video className={`video-js ${styles.video} vjs-big-play-centered`} ref={onVideo}/>
</div>
)
}
export default VideoPlayer;
As I mentioned, I used to style video.js player this way and it always worked perfectly until I switched to Next.js. Even stranger, the .video class doesn't appear in the browser's developer tools when inspecting the page.
Is there a way I could apply my custom styling properly with Next.js ?
So after looking for a workaround, I found that styling my custom video component in my global.scss file would actually work. I don't particularly know why specifically but here's how you can do:
This is my global.scss file:
/* Base styling */
/* .class { ... } */
/* VideoJS styling -> */
.video-js.video {
* {
& :before {
text-shadow: 1px 1px 7px rgba(10, 10, 10, 0.5);
}
}
&:hover {
.vjs-big-play-button {
background-color: rgba(255, 255, 255, 1);
}
}
.vjs-big-play-button {
height: initial;
width: initial;
font-size: 5em;
line-height: 6.15rem;
padding: 1em;
border: none;
border-radius: 9999px;
background-color: rgba(255, 255, 255, 0.8);
& :before {
margin: 0;
padding: 0;
}
}
.vjs-control-bar {
width: 90%;
min-height: 5em;
margin: 2rem auto;
padding: 0 1em;
border-radius: 1em;
}
}
So you won't have to import '../styles/video-player/module.scss' in VideoPlayer React component

How to change a slide out drawer in react grid to position fixed

I am trying to create a slide out drawer exactly like the one present in JIRA.
Here is what JIRA looks like (notice how sidebar opens and pushes content to the side):
Here is what I have managed to create in my code:
The sliding effect and shelf looks similar enough and I am happy with it. However, there is one feature that Jira has that I find quite interesting and would like to recreate in my code base. When the sidebar is closed, and the user hovers over the sliver of sidebar that remains, the sidebar opens up as if the button to open had been clicked, and it then closes when the mouse leaves the sidebar. What is really interesting to me is that the grid format does not change and the sidebar appears to not move the other content on the page which makes me believe it somehow switches to a fixed position just during this mouse over event. I am not sure how to achieve this effect and my code is currently not working. Any help would be greatly appreciated!
Here is the desired effect (notice how sidebar opens and DOES NOT push content to the side, which is different than actually clicking the button. See first gif example):
EDIT: Here is the effect for mousing in to the sidebar and the button becoming visible while in the sidebar:
Here is what I have tried so far:
(SideBar Component)
import React, { useState, useRef } from 'react';
import { Link } from 'react-router-dom';
import './RenewalSidebar.css';
function RenewalSidebar({ worksheetID }) {
const [sidebar, setSidebar] = useState(false);
const [cursorInSidebar, setCursorInSidebar] = useState(false);
const showSidebar = () => setSidebar(!sidebar);
const sidebarRef = useRef(null);
return (
<nav
ref={sidebarRef}
className={sidebar ? 'sidebar' : 'sidebar inactive'}
onMouseLeave={() => setCursorInSidebar(false)}
onMouseOver={(e) => {
if (e.target === sidebarRef.current || sidebarRef.current.contains(e.target)) {
console.log(`Hey I'm in the sidebar`);
setCursorInSidebar(true);
}
}}
data-sidebarhover={cursorInSidebar}
data-sidebaropen={!sidebar}
>
<div
role="button"
tabIndex={0}
className="hamburger"
type="button"
onClick={showSidebar}
data-open={!sidebar}
data-hover={cursorInSidebar}
onMouseEnter={() => setCursorInSidebar(true)}
onMouseLeave={() => setCursorInSidebar(false)}
>
{sidebar ? '>' : '<'}
</div>
<div className="sidebar-content">
<ul onClick={showSidebar} data-open={!sidebar}>
<li>
<Link to={`/`}>Test</Link>
</li>
<li>
<Link to={`/`}>Test</Link>
</li>
<li>
<Link to={`/`}>Test</Link>
</li>
</ul>
</div>
</nav>
);
}
export default RenewalSidebar;
Here is my css for the top level grid container I am using:
.RenewalsDetailContainer {
display: grid;
grid-template-columns: max-content 1fr;
justify-items: center;
}
And here is my css for the Sidebar component:
.sidebar {
position: relative;
/* top: 20vh;
left: -300px; */
width: 20px;
height: 100%;
/* border-radius: 0px 5px 5px 0px; */
background-color: aliceblue;
z-index: 0;
transition: width 200ms ease-out;
box-shadow: inset -10px 0 25px -25px #888;
padding: 0 10px;
}
.sidebar.inactive {
width: 300px;
z-index: 6000;
}
.sidebar ul {
margin: 0;
padding: 0;
}
.sidebar ul[data-open='false'] {
display: none;
}
.sidebar li a {
display: block;
border: none;
background-color: white;
padding: 14px 28px;
font-size: 16px;
margin: 10px 10px 10px 10px;
width: auto;
text-align: center;
}
/* .sidebar[data-sidebaropen='false'][data-sidebarhover='true'] {
z-index: -9000;
} */
.sidebar[data-sidebaropen='false'][data-sidebarhover='true'] .sidebar-content {
position: fixed;
width: 300px;
top: 0;
left: 0;
background-color: purple;
}
.hamburger {
color: rgb(107, 119, 140);
background-color: rgb(255, 255, 255);
height: 24px;
border: none;
outline: 0;
width: 24px;
top: 32px;
position: absolute;
right: 0px;
font-size: 15px;
font-weight: bold;
border-radius: 50%;
transform: translateX(50%);
display: grid;
place-items: center;
transition: all 500ms linear, color 100ms linear, opacity 350ms cubic-bezier(0.2, 0, 0, 1);
box-shadow: rgb(9 30 66 / 8%) 0px 0px 0px 1px, rgb(9 30 66 / 8%) 0px 2px 4px 1px;
}
.hamburger:hover {
background-color: #4c9aff;
color: white;
box-shadow: none;
cursor: pointer;
}
.hamburger[data-open='true'] {
opacity: 0;
}
.hamburger[data-open='true']:hover {
opacity: 1;
}
.hamburger[data-open='true'][data-hover='true'] {
opacity: 1;
}
.hamburger:after,
.hamburger:before,
.hamburger div {
background-color: #0076c7;
/* margin: 7px 0; */
border-radius: 3px;
content: '';
display: block;
transition: all 300ms ease-in-out;
}
.sidebar-content {
position: relative;
width: 100%;
height: 100%;
}
.sidebar-content .sidebar.active .hamburger div {
transform: scale(0);
}
And finally...here is a Code sandbox link I have created to help you test the code. Click me!
I believe I have addressed all of your feature requests in this updated CodeSandbox:
https://codesandbox.io/s/jira-inspired-menu-bnyd8
The crux of the solution was to decouple the SideBar content from the mechanics of how that column is propped open, depending on UI state. It required a bit of nesting and absolute positioning to get the job done.
The content width of the SideBar is measured with getBoundingClientRect() when the panel is opened up, and then that value is stored in state. That value is then used to control the width of the SideBar container when it is open, as well as the shim width (which is what actually pushes the main content to the side when the SideBar is fully opened) and hamburger x coordinate.
Relevant code for my solution is in SideBar.js and SideBar.css in the CodeSandbox link above.
Preview of UI in action:
I have made few changes to accommodate this.
Nesting of sidebar and button will raise conflict between onMouseEnter events, you won't be able to click on the button. (Moved the button outside nav)
Position absolute does not push the content. And you can use react inline styles like this :
style={{position: cursorInSidebar && !sidebar ? "absolute" : "relative"}}
Added isOpen to track if the sidebar is open. Either by button click or mouse hover.
onClick events should set cursorInSidebar.
const SideBar = () => {
const [sidebar, setSidebar] = useState(false);
const [cursorInSidebar, setCursorInSidebar] = useState(false);
const showSidebar = (isOpen) => {
setSidebar(!isOpen);
setCursorInSidebar(false);
};
const sidebarRef = useRef(null);
const enterSideBar = () => {
setCursorInSidebar(true);
};
const leaveSideBar = () => {
setCursorInSidebar(false);
};
const isOpen = sidebar || cursorInSidebar;
return (
<div className="divSid">
<div
role="button"
tabIndex={0}
className="hamburger"
type="button"
onClick={() => showSidebar(isOpen)}
data-open={isOpen}
>
{isOpen ? "<" : ">"}
</div>
<nav
ref={sidebarRef}
style={{
position: cursorInSidebar && !sidebar ? "absolute" : "relative"
}}
className={isOpen ? "sidebar inactive" : "sidebar"}
data-sidebaropen={isOpen}
onMouseEnter={enterSideBar}
onMouseLeave={leaveSideBar}
>
<div className="sidebar-content">
<ul onClick={() => showSidebar(isOpen)} data-open={isOpen}>
<li>Test</li>
<li>Test</li>
<li>Test</li>
</ul>
</div>
</nav>
</div>
);
};
While moving button outside nav, alignment of components will break. Here is the working code.

What is the main cause of box-shadow not to work

Hello I have to been trying to search for a solution to my problem that is my box-shadow not working, I have seen other question on Stack Overflow that are similar but the all did not solve my problem can I please get some help
Code below is my React Component
import React from "react";
import "../StyleSheet/MainDashBaordWindow.css";
const HomeDashContent = () => {
return (
<div className="DashBoardContent">
<h1 className="DashBoardContent__header">Welcome Back!</h1>
<div className="DashBoarContent__mainWindow">
<div className="mainWindow__cards left-card">
<h2>On Going Shipments</h2>
</div>
<div className="mainWindow__cards right-card">
<h2>Finished Shipments</h2>
</div>
</div>
</div>
);
};
export default HomeDashContent;
Code below is my stylesheet
.DashBoardContent {
flex: 0.8;
display: flex;
flex-direction: column;
align-items: center;
}
.DashBoardContent__header {
font-weight: bolder;
margin-bottom: 2em;
}
.DashBoarContent__mainWindow {
display: flex;
}
.mainWindow__cards {
background-color: #f5f5f5f5;
padding: 4em 2em;
height: 30vh;
transition: transform 0.4s;
box-shadow: 2rem 2.5rem 2rem solid lightslategray;
}
.mainWindow__cards:hover {
transform: scale(1.1);
}
.left-card {
margin-right: 5em;
}
.right-card {
margin-left: 5em;
}
'Solid' value is not available for the box-shadow property. Just try to put a length value like 1px for the spread value(which is the fourth property value for box-shadow) instead of solid and it's gonna work.

css React onclick show component

I am learning css and react and a bit confused how to display:block for a component when a user clicks a button myButton. And to hide the component when the user clicks it again.
I am using mobile and desktop views and want the button to not show in desktop view, it will only show in Mobile view.
In Mobile view once the user clicks the button toggle component needs to show. That is where I dont know how onclick I can say for Toggle css to display:block to show entire component. Toggle shows in desktop view.
Here is code map.tsx
<div className={styles.controlsContainer}>
<Toggle />
</div>
<div className={styles.button_about}>
<AboutPopup />
<Button id=myButton
type="primary"
icon={<FilterOutlined />}
className={styles.filterbutton} onClick== --- How to say to enable toggle css to block??
></Button>
</div>
Here is how my map.module.scss looks like
.toggle {
width: 244px;
background: #ffffff;
border: 1px solid #d9d9d9;
box-sizing: border-box;
border-radius: 4px;
display: flex;
align-items: center;
float: left;
}
#media screen and (max-width: $mobileMax) {
.toggle {
display: none;
}
}
.button {
&_about {
#include for-desktop {
position: absolute;
bottom: 2em;
right: 2em;
}
#include for-mobile {
position: absolute;
top: 2em;
z-index: 1;
right: 2em;
z-index: 1;
}
}
}
.filterbutton {
width: 40px;
height: 40px;
left: calc(50% - 40px / 2);
top: calc(50% - 40px / 2);
background: $color-blue;
border-radius: 100px;
color: #83888c;
#include for-desktop {
display: none;
}
#include for-mobile {
position: absolute;
top: 4em;
right: 2em;
}
}
----- Update 2
So I did something like this
const [isShow, setIsShow] = React.useState(true);
const handleClick = () => {
setIsShow((prev) => !prev);
console.log(isShow);
};
return
(
<div className={styles.controlsContainer}>
<Toggle
className= {isShow ? {styles.toggle_show} : {styles.toggle_hide}}
/>
)
But I am getting a parsing error on styles.toggle_show Parsing error: ',' expected.eslt
maybe this could help
import React from "react";
import "./styles.css";
export default function App() {
const [isShow, setIsShow] = React.useState(false);
const handleClick = () => setIsShow((prev) => !prev);
return (
<>
<div className={isShow ? "show" : "hide"}>my toggling component</div>
<button onClick={handleClick}>toggle show</button>
</>
);
}
css:
.show {
display: block;
}
.hide {
display: none;
}

material-ui icon button highlights with an elliptical background when cursor is hovered over it

IconButton in #material-ui/core/IconButton is showing a weird elliptical background when I hover the cursor over it.
I thought it is a mistake by me, so I just copied the code from material-ui website, but the problem remains.
However, when I created new react project, and created an icon button in it, the background was the usual circle.
I'm new to react and can't figure out what is going on, I'm using icon button without any explicit styling,
App.js
import React, { Component } from 'react';
import './App.css';
import { IconButton } from '#material-ui/core';
import WorkIcon from '#material-ui/icons/Work';
import CssBaseline from '#material-ui/core/CssBaseline';
class App extends Component {
render() {
return (
<div>
<CssBaseline />
<IconButton>
<WorkIcon />
</IconButton>
</div>
);
}
}
export default App;
App.css
.App {
text-align: center;
}
.App-logo {
animation: App-logo-spin infinite 20s linear;
height: 80px;
}
.App-header {
background-color: #222;
height: 150px;
padding: 20px;
color: white;
}
.App-title {
font-size: 1.5em;
}
.App-intro {
font-size: large;
}
#keyframes App-logo-spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.MuiCardContent-root-29 {
display: inline-block;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 500px;
height: 300px;
margin: auto;
background-color: #f3f3f3;
}
.login {
margin-top: 50px;
margin-left: 50px;
}
.form-group {
margin-bottom: 35px;
}
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from "react-redux";
import './index.css';
import App from './App';
import store from "./store/index";
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<Provider store={store}>
<App />
</Provider>, document.getElementById('root'));
registerServiceWorker();
index.css
body {
background-color : #484848;
margin: 0;
padding: 0;
}
h1 {
color : #000000;
text-align : center;
font-family: "SIMPSON";
}
form {
width: 300px;
margin: 50px auto;
}
button {
background-color: #4CAF50;
color: white;
padding: 14px 20px;
margin: 8px 0;
border: none;
cursor: pointer;
width: 100%;
opacity: 0.9;
width: 100px;
}
.tableHeader {
background-color: green !important;
}
.header {
color: green;
font-weight: bold;
}
.edit {
height: 30px;
cursor: pointer;
}
.delete {
height: 20px;
cursor: pointer;
padding-left: 10px;
}
This problem persists in my whole project wherever I use icon buttons, and not just with this file only. And when I use this same file in a new project it works as expected: No elliptical backgrounds.
EDIT:
The accepted answer works well. In my also case I tried setting the width in button of index.css to auto and it fixed the error too.
This is what I did to remove the elliptical shape:
<IconButton style={{borderRadius: 0}}>
<DeleteIcon/>
</IconButton>
Now, it will be a rectangular shape when hovered.
I don't know why the above two solutions didn't work for me. So I added margin and width to the parent element and padding-right to the child element in App.css.
//For the buttons on top
button.MuiButtonBase-root {
margin: 10px;
width: 50px;
}
button.MuiButtonBase-root span span {
padding-right: 50px;
}
//For the checkboxes
span.MuiButtonBase-root {
margin-left: 10px;
width: 45px;
}
span.MuiButtonBase-root span {
padding-right: 10px;
}
The problem is the button CSS in your index.css. It is setting the width of all buttons to 100px. IconButton is implemented via a button tag around the icon.
Fixing the look of IconButton is easy -- just remove that button CSS. The more tedious part is that presumably you want that button styling on all your other buttons.
One way to handle this is to change the following in index.css:
button {
background-color: #4CAF50;
color: white;
padding: 14px 20px;
margin: 8px 0;
border: none;
cursor: pointer;
width: 100%;
opacity: 0.9;
width: 100px;
}
to be a CSS class rather than targeting all buttons:
.standard-button {
background-color: #4CAF50;
color: white;
padding: 14px 20px;
margin: 8px 0;
border: none;
cursor: pointer;
width: 100%;
opacity: 0.9;
width: 100px;
}
and then change places where you are rendering button elements to use:
<button className="standard-button">
instead of just <button>.
This worked for me
<IconButton style={{height:"45px",marginTop:"20px"}}>
<DeleteIcon/>
</IconButton>
Hi you can override ripple root and child style to change border radius or background color.
const useStyles = makeStyles({
root: {
borderRadius: 0, // <---- icon button root style
'.MuiTouchRipple-ripple .MuiTouchRipple-child': { // <----this should change ripple style when clicked or touched
borderRadius: 0,
backgroundColor: 'red'
},
},
});
<IconButton className={classes.rippleRoot}>
<WorkIcon />
</IconButton>
OR MUI5 with sx props
<IconButton
sx={{
borderRadius: 0,
'.MuiTouchRipple-ripple .MuiTouchRipple-child': {
borderRadius: 0,
backgroundColor: 'red',
},
}}
>
<WorkIcon />
</IconButton>
use height and width with same value to have circular shade on hover-
<IconButton sx={{height:"40px",width:"40px"}}>
<WorkIcon />
</IconButton>

Resources