Problem accessing styled component nth-child - reactjs

Sorry for my bad English. I have some difficulty accessing the children of a menu in styled component. This is my component I want to access the AccountMenuItem children, I want to apply a higher height to the first and last children, but I can not access the way and the way.
CodeSandbox
I tried many options, but to no avail:
These are the last ones.
&:nth-child(2) ${AccountMenuItem} {
height: 80px;
}
&${AccountMenuItem}:nth-child(2) {
height: 80px;
}
<AccountMenu>
{menuItems.map((item, indice) => {
return (
<AccountMenuItem key={indice}>
<MenuImage src={item.icon} alt={item.text} />
<MenuItem>{item.text}</MenuItem>
</AccountMenuItem>
)
})}
</AccountMenu
const AccountMenuItem = styled.span`
height: 40px;
color: ${props => props.theme.primary[100]};
display: flex;
align-items: center;
text-decoration: none;
background-color: ${props => props.theme.TextPalette[100]};
&:hover {
background-color: rgba(131, 0, 196, 0.05);
font-weight: bold;
}
`
const AccountMenu = styled.div`
display: inline-block;
visibility: hidden;
position: absolute;
bottom: -240px;
width: 198px;
right: 0;
z-index: 99999;
text-decoration: none;
background-color: #f1f1f1;
border-bottom: 5px solid ${props => props.theme.primary[100]};
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
#media only screen and (min-width: 720px) {
left: -55px;
bottom: -240px;
}
&:hover {
visibility: visible;
}
&::after {
content: '';
position: absolute;
bottom: 100%;
left: 90%;
margin-left: -10px;
border-width: 10px;
border-style: solid;
border-color: transparent transparent #12ff92 transparent;
#media only screen and (min-width: 720px) {
margin-right: 0;
height: 120px;
left: 50%;
}
}
&:nth-child(2) ${AccountMenuItem} {
height: 80px;
}
`

There are two solutions to this. I have implemented both solutions in this link, one by setting background of the second child to black, and another by setting the background of the third child to blue.
Code: https://codesandbox.io/s/determined-tree-0l1hs
The important bit is that you were missing a space between & and the child's identifier in your first example. It should be like this:
// v-- Space here!!
& ${AccountMenuItem}:nth-child(3) {
background: blue;
}
The difference of the space is the same as this difference in traditional CSS:
.account-menu.account-menu-item // means an element that has both classes
.account-menu .account-menu-item // means the second element is a descendant of the first
The other way to do this, which I prefer, is just define the rule in the AccountMenuItem instead of defining it in the parent. That way you can skip the weird inheritance stuff and apply the style directly. So in AccountMenuItem you just need this:
&:nth-child(2) {
background: black;
}

Related

Is it possible to use the same React component with different CSS, using css modules?

I found the React CSS modules usefull, but having problem when I tried to reuse the same component with a little modified css I stuck. For example I created Neon glowing button, but now need to change only the width of the Button and some additional small changes in the css.
The only option I see is component without css and for every different case need to rewrite the whole css. Is there a smarter way?
import React from "react";
import styles from "./index.module.css";
import { Link } from "react-router-dom";
const GlowingButton = ({ title, path }) => {
return (
<div className={styles.buttonWrapper}>
<Link className={styles.button} to={path}>
<button className={styles["glow-on-hover"]}>{title}</button>
</Link>
</div>
);
};
export default GlowingButton;
And here is index.module.css
.buttonWrapper {
margin: 0px;
padding: 0px;
display: flex;
justify-content: center;
align-items: center;
background: transparent;
font-family: "consolas";
}
.button {
margin: 0;
padding: 0;
width: 80%;
height: 8vh;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
background: #100f;
text-decoration: none;
}
.glow-on-hover {
width: 400px;
height: 50px;
border: none;
outline: none;
color: #fff;
background: #111;
cursor: pointer;
position: relative;
z-index: 0;
border-radius: 10px;
}
.glow-on-hover:before {
content: "";
background: linear-gradient(
45deg,
#ff0000,
#ff7300,
#fffb00,
#48ff00,
#00ffd5,
#002bff,
#7a00ff,
#ff00c8,
#ff0000
);
position: absolute;
top: -2px;
left: -2px;
background-size: 400%;
z-index: -1;
filter: blur(5px);
width: calc(100% + 4px);
height: calc(100% + 4px);
animation: glowing 20s linear infinite;
opacity: 0;
transition: opacity 0.3s ease-in-out;
border-radius: 10px;
}
.glow-on-hover:active {
color: #000;
}
.glow-on-hover:active:after {
background: transparent;
}
.glow-on-hover:hover:before {
opacity: 1;
}
.glow-on-hover:after {
z-index: -1;
content: "";
position: absolute;
width: 100%;
height: 100%;
background: #111;
left: 0;
top: 0;
border-radius: 10px;
}
#keyframes glowing {
0% {
background-position: 0 0;
}
50% {
background-position: 400% 0;
}
100% {
background-position: 0 0;
}
}

Bottom navigation bar animation

I want to make it so that when you click on one of the icons, a certain strip appears under it, which will mean that the person is on this page (something like this)
At the moment, my navbar looks like this
Here's what I have at the moment (HTML):
let marker = document.querySelector('#marker');
let item = document.querySelectorAll('nav a .MuiSvgIcon-root');
function indicator(e) {
marker.style.left = e.offsetLeft + "px";
marker.style.width = e.offsetWidth + "px";
}
item.forEach(link => {
link.addEventListener('click', (e) => {
indicator(e.target)
})
})
body {
position: fixed;
bottom: 0;
left: 0;
background: #f2f2f2;
width: 100%;
height: 60px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 40px;
border-top: 1px solid lightgray;
z-index: 100;
}
.MuiSvgIcon-root {
font-size: 35px;
cursor: pointer;
transition: 0.3s cubic-bezier(0.1, 0.1, 0.5, 1.4);
:hover {
transform: translateY(-5px);
}
}
#marker {
position: absolute;
height: 4px;
width: 0;
background: #000;
bottom: 8px;
left: 0;
transition: 0.5s;
border-radius: 4px;
}
<div id="marker"></div>
<HomeIcon/>
<TimelineIcon/>
<AccountCircleIcon/>
<ExploreIcon/>
.MuiSvgIcon-root there is defining all icons.
Your js code is correct. You should check your HTML and CSS. Because their structure is important

styled-component dropdown make parent:hover color stay while child:hover

I'm trying to make the parent background color stay changed on hover as I continue to hover over the dropdown items.
https://zqy0v.csb.app/dropdowns < dropdown
import React from "react";
import styled from "styled-components";
//============================================ styles =============================================
const DivDropdownContent = styled.div`
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 24.7rem;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
`;
const DivDropdown = styled.div`
position: relative;
display: inline-block;
&:hover ${DivDropdownContent} {
display: block;
}
`;
const SpanDropdownTitle = styled.div`
font-size: 1.6rem;
font-weight: bold;
padding: 2rem 6rem;
border-radius: 0.6rem;
border: 1px solid black;
&:hover {
cursor: pointer;
}
`;
const ItemDropdown = styled.p`
padding: 1rem;
&:hover {
cursor: pointer;
background: lightgray;
}
`;
//=========================================== component ===========================================
const BasicDropdown = props => {
return (
<DivDropdown>
<SpanDropdownTitle>Basic Dropdown</SpanDropdownTitle>
<DivDropdownContent>
<ItemDropdown>Item 1</ItemDropdown>
<ItemDropdown>Item 2</ItemDropdown>
<ItemDropdown>Item 3</ItemDropdown>
</DivDropdownContent>
</DivDropdown>
);
};
export default BasicDropdown;
Basically I would like the background color to stay changed for the parent while hovering over the child items in the dropdown, much like is done here https://woocommerce.com/
Is there an easy way to do this, or do I have to start getting complicated with using state and onPointerEnter and onPointerLeave?
I finally ended up finding the solution, and am a bit embarrassed.
const DivDropdown = styled.div`
position: relative;
display: inline-block;
&:hover ${DivDropdownContent} {
display: block;
}
`;
The Issue: ^This was only targeting the nested component when I added the background cover to the hover.
const DivDropdown = styled.div`
position: relative;
display: inline-block;
&:hover {
background: lightgray;
}
&:hover ${DivDropdownContent} {
display: block;
}
`;
The Fix: ^By adding the above, I was able to correct the behavior.
I'm going to leave this question up, because I wasn't able to find much tutorials on this through my internet searching. I think this is a fairly clean solution and think it will help others searching.

Bootstrap AngularJS fullscreen table

I have a table with a lot of columns and a horizontal scrollbar. I'm searshing a way to show it in fullscreen, like you can do in gmail when you want to see an mail attachement with a glyphicon-resize-full
If someone have an idea :)
edit : I'm trying with this :
<div id="overlayContainer" class="overlay">
<div id="overlayContent" class="overlay-content">
</div>
using a css to have a bigger table on a black background
<style>
.overlay {
height: 0;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0, 0.9);
overflow-x: hidden;
transition: 0.5s;
}
.overlay-content {
position: relative;
top: 25%;
width: 100%;
text-align: center;
margin-top: 30px;
}
.overlay a {
padding: 8px;
text-decoration: none;
font-size: 36px;
color: #818181;
display: block;
transition: 0.3s;
}
.overlay a:hover, .overlay a:focus {
color: #f1f1f1;
}
.overlay .closebtn {
position: absolute;
top: 20px;
right: 45px;
font-size: 60px;
}
#media screen and (max-height: 450px) {
.overlay a {
font-size: 20px;
}
.overlay .closebtn {
font-size: 40px;
top: 15px;
right: 35px;
}
}
and I fill the div overlayContent or close it by this way :
$scope.fullScreenElement = function () {
document.getElementById("overlayContainer").style.height = "100%";
document.getElementById("overlayContainer").style.width = "100%";
document.getElementById("overlayContent").innerHTML = document.getElementById("tableContent").innerHTML;
};
$scope.reduceElement = function () {
document.getElementById("overlayContainer").style.height = "0%";
document.getElementById("overlayContainer").style.width = "0%";
};
But with that I can't use JS functions of my table :(
edit : Here is an example : http://plnkr.co/edit/1ge8r8zFANDNt2P2k0kI?p=preview
I couldn't reproduce it, but table should have horizontal scrollbar and you should't see lasts columns at the right. And if you expand it, you see the entire table but javascript like click on column name to sort (it's not in my Plunker) doesn't work
edit : I tried a second time with your angular.element(document.getElementById($scope.id)).addClass("overflowFullScreen");
Nimmi, and it's better than my first try, it keeps JS functions. I continue with this, but looks good. Thank you !
final edit : I resolves lasts problems caused by z-index and a missing vertical scrollbar but it is done ! Thank you for your help !

Create tabs with merge area

How can I create Tabs with Angular-Material look like this picture below :
(I don't know how to describe it in English so I call it is "merges tab" )
Here's a stab at it - CodePen. I think it can be improved.
Markup
Some description
Tab One
Tab Two
Tab Three
Tab Four
CSS
#myTabs {
margin-top: -40px;
z-index: 0;
}
#myTabs md-tab-item {
border: 1px solid black;
}
#myTabs md-tabs-canvas,
#myTabs md-pagination-wrapper {
height: 100px
}
#myTabs .md-tab {
line-height: 80px
}
#tabsDescription {
height: 40px;
z-index: 1;
text-align: center;
}
#tabsDescription {
margin-left: -20px;
background: white;
height: 40px;
width: 4px;
text-align: center;
}
#tabsDescription p {
margin: 5px -60px;
white-space: nowrap;
}

Resources