React custom element is in DOM, but not visible - html

I am trying to create an element in React, but I cannot get it to be visible. It shows up in the Elements tab of the Chrome developer console, but when I hover over it there it doesn't even show a location. I have other custom elements that work fine, it is this in particular that is not rendering. Here is the code defining the element:
import React from "react";
import ReactDom from "react-dom";
const Modal = (props) => {
const [domReady, setDomReady] = React.useState(false)
React.useEffect(() => {
setDomReady(true)
})
return domReady?ReactDom.createPortal(
<>
<div className="modal">
TEST
</div>
<div onClick={() => {}} className="backdrop">
</div>
</>,
document.getElementById('modal-root')
):null
}
export default Modal;
Here is the CSS that affects it, though it is worth noting that even without this CSS I see nothing:
.modal {
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
border-radius: 6px;
background-color: white;
padding: 1rem;
text-align: center;
width: 30rem;
z-index: 10;
position: fixed;
top: 0;
left: 0;
}
.backdrop {
position: fixed;
z-index: 1;
background-color: rgba(0, 0, 0, 0.75);
width: 100%;
height: 100vh;
top: 0;
left: 0;
}
Edit: Here is the file which uses the component:
import { useState } from 'react';
//import Loading from '../Loading/Loading';
import './Income.css';
import { useNavigate } from 'react-router-dom';
import IncomeRow from '../../components/IncomeRow/IncomeRow';
import Button from '../../components/Button/Button';
import Modal from '../../components/Modal/Modal';
const Income = () => {
//Initializing
const navigate = useNavigate();
// modal visibility states
const [editModalVisible, setEditModalVisibility] = useState(false);
const [deleteModalVisible, setDeleteModalVisibility] = useState(false);
const [addModalVisible, setAddModalVisibility] = useState(false);
// show modal to edit income
const onEditClick = () => {
setEditModalVisibility(true);
}
const onDismissEditModal = () => {
setEditModalVisibility(false);
}
//returning JSX
return (
<>
<div className='Incomes'>
{/* TODO: make these autogenerate from database */}
<IncomeRow name="income 1" source="Company 1" date="1/1/2022" amount={123.45} id="1" editFunction={onEditClick}/>
<IncomeRow name="income 2" source="Company 2" date="7/31/2022" amount={420.69} id="2"editFunction={onEditClick}/>
</div>
<Button text="Add Income"/>
<Modal dismissModal={onDismissEditModal}/>
</>
);
}
export default Income
Here is App.js, which holds the base of the layout:
import React, { useState} from 'react';
import './App.css';
import Navbar from './components/Navbar/Navbar';
import 'bootstrap/dist/css/bootstrap.min.css';
//import { ThemeContext, themes } from './context/themeContext';
import { Outlet, useNavigate} from 'react-router-dom';
function App() {
return (
<div className="App">
<Navbar/>
<div className='body'>
<div id='modal-root'>
<Outlet/>
</div>
</div>
</div>
);
}
export default App;

Related

How to change checkbox checked color with react?

There is a checkbox component:
import React, { InputHTMLAttributes } from "react";
import styled, { css } from "styled-components";
export const CheckBox: React.FC<InputHTMLAttributes<HTMLInputElement>> = (
props
) => {
return <Input type="checkbox" {...props} />;
};
const Input = styled.input`
${({ theme }) => css`
border: 1px solid white;
&:checked {
background-color: green;
border-color: green;
}
`}
`;
I want to set its checked color to another but doesn't work. It's still the default blue background color.
I hope:
Before
After
You can create own your component for that but it takes a lot of time.
Checkout into sandbox

Styled-components: Style not updated after switching from mobile

Here:
Open the app in desktop width, notice the div has green background
Reduce browser width to mobile, the div background should change to gray
Again, increase browser width to desktop, notice the gray background remains, instead of green
What should have happened
The background in last step should be green as in the first step, isn't it?
Logging value of isMobile does seem to show it is being updated.
Here is also code:
import React from 'react';
import styled from 'styled-components';
import { useMediaQuery } from 'react-responsive';
let MenuItem = styled.div`
height: 100px;
width: 100px;
border:1px solid red;
background-color: green;
// Select those items which are children of .submenu
.submenu & {
background-color: ${({ isMobile }) => {
return isMobile && 'lightgray';
}};
}
`;
function App() {
const isMobile = useMediaQuery({ query: '(max-width: 524px)' });
return (
<div>
<div className="submenu">
<MenuItem isMobile={isMobile}>test</MenuItem>
</div>
</div>
);
}
export default App;
import React, {useEffect, useState} from 'react';
import styled from 'styled-components';
import {useMediaQuery} from 'react-responsive';
let MenuItem = styled.div`
height: 100px;
width: 100px;
border:1px solid red;
background-color: green;
`;
function App() {
const isMobile = useMediaQuery({query: '(max-width: 524px)'});
const [color, setColor] = useState('green');
useEffect(() => {
if (isMobile) setColor('silver');
else setColor('green');
}, [isMobile])
return (
<div>
<div className="submenu">
<MenuItem style={{background: color}} isMobile={isMobile}>test</MenuItem>
</div>
</div>
);
}
export default App;
You could re-write this as:
const MenuItem = styled.div`
height: 100px;
width: 100px;
border:1px solid red;
background-color: green;
`;
const SubMenu = styled.div`
${MenuItem} {
background-color: ${({ isMobile }) => (isMobile ? `red` : 'lightgray')};
}
`;
function App() {
const isMobile = useMediaQuery({ query: '(max-width: 524px)' });
return (
<>
<SubMenu isMobile={isMobile}>
<MenuItem>MenuItem in SubMenu</MenuItem>
</SubMenu>
<MenuItem>MenuItem</MenuItem>
</>
);
}
Stackblitz
It is the correct answer:
https://stackblitz.com/edit/react-t7gqwx?file=src%2FApp.js,src%2Findex.js
You shouldn't use .submenu &.

Unable to display a Component as Grid View in React.js

import React from "react";
import { useSelector } from "react-redux";
import { selectData } from "../features/dataSlice";
import ProductCard from "./ProductCard";
import { Grid } from "#material-ui/core";
import styled from "styled-components";
import style from "../style.css";
function Product() {
const products = useSelector(selectData);
const renderproducts = products.map((product) => {
//const { id, title, price, description, category, image, rating } = product;
return <ProductCard data={product} />;
});
return (
<Container>
<div>{renderproducts}</div>
</Container>
);
}
export default Product;
const Container = styled.div`
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
`;
-------------------------------------
import React from "react";
import Product from "./Product";
import styled from "styled-components";
import { Grid } from "#material-ui/core";
function ProductCard(props) {
const { data } = props;
return (
<Container>
<img src={data.image} />
</Container>
);
}
export default ProductCard;
const Container = styled.div`
padding-top: 60px;
img {
width: 100px;
height: 100px;
}
`;
const Card = styled.div`
img {
width: 60px;
height: 60px;
}
`;
I need to display all the images from the products array which Iam fetching from an API as Grid View. Above is the code for the ProductCard.js & Product.js components. I have tried to add the grid view styling in the ProductCard component also. But it just does'nt display as Grid. Please help me.
You can use grid-like.
<Grid container spacing={2}>
{products.map((p,i)=>( <Grid key={i} item xs={8}>
< ProductCard/>
</Grid>)
}
</Grid>
</Grid>
for more details, you can check https://mui.com/components/grid/

How to get my button to trigger an element

I am using nextjs to compile my code and antd framework. I am unable to style the positioning of my button, also I want my start button to trigger a set of buttons but for some reason it does not work. Below is my code
import React, { Component } from "react";
import Layout from "./Layout";
import { Radio } from "antd";
export default class PositiveAffirmation extends Component {
state = {
changeButton: false
};
toggleChangeButton = e => {
this.setState({
changeButton: e.target.value
});
};
render() {
const { changeButton } = this.state;
return (
<Layout>
<Radio.Group
defaultValue="false"
buttonStyle="solid"
onChange={this.changeButton}
className="radio-buttons"
>
<Radio.Button value={true}>Start</Radio.Button>
<Radio.Button value={false}>Stop</Radio.Button>
</Radio.Group>
{changeButton && (
<Button.Group size={size}>
<Button type="primary">Happy</Button>
<Button type="primary">Sad</Button>
<Button type="primary">Fullfiled</Button>
</Button.Group>
)}
<style jsx>{`
Radio.Button {
font-size: 100px;
margin-left: 20px;
margin-top: 5px;
margin-bottom: 5px;
display: flex;
justify-content: center;
}
`}</style>
</Layout>
);
}
}
you are calling just wrong fn change onChange={this.changeButton} to onChange={this.toggleChangeButton}

Ant Design: Vertical submenu pop up grow from bottom to top

Is it possible to display the popup of a vertical submenu "the other way around" ? I have one SubMenu item in a fixed Sidebar at the bottom of my page. It contains links for the users profile and the logout link. But since it is at the bottom of the page the submenu will open and part of it is outside the of the page.
Here is a screenshot of the current situation.
I searched for options the documentation but I couldn't find a suitable solution for the problem. So basically what I want to achieve is growing the popup from bottom to top and not top to bottom.
Here is the source for the Sidebar component. It is quite a early stage so there are still other improvements to the code to do.
import React from 'react';
import { connect } from 'react-redux';
import { Layout, Menu, Icon } from 'antd';
import { withRouter } from 'react-router-dom';
import styled from 'styled-components';
import { toggleSidebar } from '../../actions/ui';
import { logoutUser } from '../../actions/user';
const { Sider } = Layout;
const SubMenu = Menu.SubMenu;
const Logo = styled.div`
height: 32px;
background: rgba(255, 255, 255, 0.2);
margin: 16px;
`;
const UserMenu = styled(SubMenu)`
position: fixed;
text-align: center;
bottom: 0;
cursor: pointer;
height: 48px;
line-height: 48px;
color: #fff;
background: #002140;
z-index: 1;
transition: all 0.2s;
`;
const mapStateToProps = state => ({
ui: state.ui
});
const mapDispatchToProps = dispatch => {
return {
toggleSidebar: () => dispatch(toggleSidebar()),
logoutUser: () => dispatch(logoutUser())
};
};
class Sidebar extends React.Component {
componentDidMount() {}
render() {
const { ui, logoutUser } = this.props;
return (
<Sider
collapsed={ui.sidebarCollapsed}
//onCollapse={toggleSidebar} // toggle is disabled
style={{
overflow: 'auto',
height: '100vh',
position: 'fixed',
left: 0
}}
>
<Logo />
<Menu theme="dark" defaultSelectedKeys={['1']} mode="inline">
<UserMenu
key="sub1"
placement="topLeft"
title={
<span>
<Icon type="user" />
<span>User</span>
</span>
}
>
<Menu.Item onClick={logoutUser} key="3">
Logout
</Menu.Item>
<Menu.Item key="4">Profile</Menu.Item>
</UserMenu>
</Menu>
</Sider>
);
}
}
export default withRouter(
connect(
mapStateToProps,
mapDispatchToProps
)(Sidebar)
);
Is there a way to achieve this ?
Yes it should be possible. <Menu>uses the rc-menu package, and supports all the properties from this package, even if they are not documented in the and.design doc page.
Menu position is guided by the builtinPlacements property, which in turn uses https://github.com/yiminghe/dom-align, which gives you lot of flexibility in how to position the elements.