Custom Accordion Component not rendering body elements - javascript

I have a collapse/accordion component from Antd that I customized and exported from an elements folder from within my application so that I could reuse it across the app.
When I import it and include it inside another component I can't render any of the body elements inside. Does anyone have any idea why this is happening and if there's a way around it?
Also as a smaller side issue when the body of the accordion opens to display, the whitespace doesn't fill the entire container and it looks like there's a grey column running down the right side.
I've included a code sandbox here to better show what I mean
Custom Collapse Component
import React, { useState } from "react";
import styled from "styled-components";
import { Collapse as AntCollapse } from "antd";
const StyledCollapse = styled(AntCollapse)`
&&& {
border: none;
border-radius: 0px;
background-color: #f7f7f7;
box-shadow: none;
}
`;
const CustomCollapse = props => {
const [disabled, setDisabled] = useState(true);
return (
<StyledCollapse onChange={() => setDisabled(prev => !prev)}>
<AntCollapse.Panel
header={props.header}
key="1"
showArrow={false}
bordered={false}
extra={<p style={{ color: "#0076de" }}>{disabled ? "SHOW" : "HIDE"}</p>}
/>
</StyledCollapse>
);
};
export default CustomCollapse;
Main Component
import React from "react";
import ReactDOM from "react-dom";
import styled from "styled-components";
import "antd/dist/antd.css";
import AntCollapse from "./CustomCollapse";
const Flexbox = styled.div`
font-family: sans-serif;
flex-direction: column;
display: flex;
justify-content: center;
border: solid 1px palevioletred;
padding: 10%;
margin: 10%;
`;
const ConfigurationOptions = () => (
<Flexbox>
<AntCollapse header="configuration test">
<h1>Test</h1>
<p>Test Paragraph</p>
<p>Test Paragraph</p>
</AntCollapse>
</Flexbox>
);
const rootElement = document.getElementById("root");
ReactDOM.render(<ConfigurationOptions />, rootElement);

You forgot to pass down the children in your custom collapse component.
To get it to work, do this:
const CustomCollapse = props => {
const [disabled, setDisabled] = useState(true);
return (
<StyledCollapse onChange={() => setDisabled(prev => !prev)}>
<AntCollapse.Panel
header={props.header}
key="1"
showArrow={false}
bordered={false}
extra={<p style={{ color: "#0076de" }}>{disabled ? "SHOW" : "HIDE"}</p>}
>
{props.children}
</AntCollapse.Panel>
</StyledCollapse>
);
};
(also to get the weird grey side column off the side you should do it like this:
const CustomCollapse = props => {
const [disabled, setDisabled] = useState(true);
return (
<StyledCollapse onChange={() => setDisabled(prev => !prev)}>
<AntCollapse.Panel
header={
<span>
{props.header}
<span style={{ color: "#0076de", float: "right" }}>
{disabled ? "SHOW" : "HIDE"}
</span>
</span>
}
key="1"
showArrow={false}
bordered={false}
>
{props.children}
</AntCollapse.Panel>
</StyledCollapse>
);
};
)

Related

Why is my React Webcam screenshot appearing as a black image on the screen?

import "./webcam.css"
import React, { useRef, useState, useCallback } from 'react';
import Webcam from 'react-webcam';
import axios from "axios";
import { Button, ButtonGroup } from "#mui/material"
import { FileUpload, RefreshRounded, CameraAltOutlined } from '#mui/icons-material';
import Navbar from '../Navbar/Navbar';
export default function WebcamSample() {
const videoElement = useRef(null);
const [url, setUrl] = useState("");
const videoConstraints = useState({
width: 450,
height: 500,
facingMode: "mirror"
});
const onUserMedia = (e) => console.log(e);
const capturePhoto = useCallback(async () => {
let stream = videoElement.current.stream;
const tracks = stream.getTracks();
await tracks.forEach(track => track.stop());
const imageSrc = videoElement.current.getScreenshot();
setUrl(imageSrc);
}, [videoElement]);
const refreshCapture = () => {
setUrl(null);
};
const uploadPhoto = () => {
console.log(url);
axios.post("http://localhost:3001/vision", {image: url}).then((res) => {
console.log(res);
});
refreshCapture();
};
return (
<>
<Navbar />
<div id="myDiv">
<div id="camView" >
{!url ? (
<Webcam
audio={false}
ref={videoElement}
mirrored={true}
videoConstraints={videoConstraints}
onUserMedia={onUserMedia}
screenshotFormat="image/png"
style={{borderRadius: '15px',}}
/>
) : (
<img id="screengrab" src={url} alt="Screenshot" style={{borderRadius: '15px',}}/>
)}
</div>
<div className="buttons">
<ButtonGroup variant="contained">
<Button
size="small"
endIcon={<CameraAltOutlined />}
onClick={() => capturePhoto()}
>Capture Image</Button>
<Button
size="small"
endIcon={<RefreshRounded />}
onClick={() => refreshCapture()}
>Refresh</Button>
{url &&
<Button
size="small"
endIcon={<FileUpload />}
onClick={() => uploadPhoto()}
>Upload</Button>
}
</ButtonGroup>
</div>
</div>
</>
);
};
My CSS File Below. My aim was to use a div to create a border around the camera.
#myDiv{
background-image:url("../../Assets/Background.svg");
background-size: cover;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
#camView{
min-height: 490px;
max-height: 490px;
background-color: #133275;
min-width:645px;
padding-top: 0.2%;
border-radius: 15px;
margin-bottom: 15%;
position:absolute;
}
.buttons
{
padding-top: 1%;
margin-top:15%;
position:absolute;
}
My buttons are moving when I change window size but I would also like them to stay in the same spot.
The Webcam Screenshot was showing before but now it is only showing a black screen. Ideally once the user presses the "Capture Image" button the react webcam takes a screenshot of the current image on the camera and displays it over it. This functionality is technically working except the image showing is black.

Reactjs react-bootstrap modal "container" property

I have modal and want to put/open in container, with modal's native property "container", but as soon as I specify class name of the container element, it shows error TypeError: Cannot use 'in' operator to search for 'current' in config
I created example SandBox
Thank you
I'm not entirely sure if this is what you're aiming for, but here's a bootstrap modal that is contained within a div.
Demo
Code
App.js
import { useEffect, useState, useRef } from "react";
import Config from "./Config";
export default function App() {
// create a container ref
const containerRef = useRef(null);
const [show, setShow] = useState(false);
const [isLoading, setLoading] = useState(true);
const hideModal = () => {
setShow(false);
};
useEffect(() => {
// make sure the DOM node is assigned to the containerRef.current property
if (isLoading && containerRef && containerRef.current) setLoading(false);
}, [isLoading]);
return (
<div className="app">
<div className="container">
<div className="row">
<div className="row-items col-3">
<button onClick={() => setShow(true)}>Show</button>
<button onClick={() => setShow(false)}>Close</button>
<hr />
<button>Info</button>
<button>Tests</button>
</div>
<div ref={containerRef} className="modal-container row-items col-9">
Modal should appear here...
<Config
ref={!isLoading ? containerRef.current : null}
hideModal={hideModal}
show={show}
/>
</div>
</div>
</div>
</div>
);
}
Config.js
import { forwardRef } from "react";
import { Modal } from "react-bootstrap";
/*
Forwards the "containerRef" to the "Modal"
The "Modal" component will then be inserted
within the "modal-container" div
*/
const Config = forwardRef(({ hideModal, show }, ref) => (
<Modal
container={ref}
show={show}
backdrop="static"
keyboard={false}
size="md"
centered
>
<div className="analysis-config-header d-block-header">
<i className="fas fa-info-circle align-middle text-info" />
Before we move on...
</div>
<div className="analysis-config-body d-block-body">Options</div>
<div className="analysis-config-action-buttons d-block-action-buttons">
<hr />
<button className="btn btn-danger btn-sm">Save</button>
<button onClick={hideModal} className="btn btn-secondary btn-sm">
Cancel
</button>
</div>
</Modal>
));
export default Config;
index.js
import ReactDOM from "react-dom";
import App from "./App";
import "bootstrap/dist/css/bootstrap.min.css";
import "./styles.css";
ReactDOM.render(<App />, document.getElementById("root"));
styles.css
html,
body,
#root {
min-height: 100vh;
width: 100%;
margin: 0;
padding: 0;
}
.app {
padding: 20px;
}
/* prevents the modal content from bleeding into the container borders */
.modal-content {
margin: auto 20px;
}
/* allows child elements to be positioned relative to the parent div */
.modal-container {
position: relative;
}
/* positions the grey background relative to the parent div */
.modal-backdrop {
position: relative;
width: 100%;
height: calc(100% - 40px);
}
/* positions the modal within the parent div, but in front of the grey
background */
.modal {
position: absolute;
}
.row-items {
border: 1px solid red;
height: 300px;
padding-top: 5px;
}

How to implement color in the button commponent in React

I want to implement a color option in my button components to use it in all my global components so I can change the text and color Dynamically
is it correct?
import React from 'react';
import './Button.css';
const Button = ({text, BtnVersion1}) => {
return (
{text}
)
}
export default Button;
<Button style={{color: "red"}} text="SHOP NOW" />
Your component code seems to be fully correct. But when using your component you have to pass props this way:
<Button text={"SHOP NOW"} BtnVersion1={"red"} />
This is where styled components can be very useful. Where you're declaring 'style' on the component, that is an inline style and would only exist on that instance of the button. You can pass a prop, say 'btnColor' to the button which is used by the styled component to change the color. See below.
import React from 'react';
import styled from 'styled-component';
import './Button.css';
const StyledButton = styled.a`
background-color: ${props => props.btnColor ? props.btnColor : 'red'};
`
const Button = ({
text,
btnColor
}) => {
return (
<StyledButton href="#" btnColor={btnColor} className="buy">{text}</StyledButton>
)
}
export default Button;
<Button btnColor='red' text="SHOP NOW" />
You can see above in the StyledButton that if we provide the btnColor prop than use that color, else default to 'red.'
For more information on styled components - https://styled-components.com/
You can have a more "dynamic" way of doing it (so your instance of <Button> doesn't change):
import React from 'react';
import './Button.css';
const Button = ({ text, style }) => {
return (
{text}
)
}
export default Button;
<Button style={{ color: "red" }} text="SHOP NOW" />
If you want to just control the color (or other properties) you can do something like:
import React from 'react';
import './Button.css';
const Button = ({ text, color }) => {
return (
{text}
)
}
export default Button;
<Button color="red" text="SHOP NOW" />
You might want to use your component this way:
The advantage here is that you can pass all your custom styles for every single one of your buttons.
const Button = ({text, style}) => {
return (
{text}
);
};
ReactDOM.render(<Button style={{color: "red"}} text="SHOP NOW" />, document.querySelector("#root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="root">
<!-- Your root container -->
</div>
Donot use anchor tag as a button in react , If you want to know the reason read this doc
https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/anchor-is-valid.md
I think best way to style a button is using styled component , I have given an example code in this sandbox , you can pass props for things only you want to change like for background, if no value is given it will take default color
try it
code :
import "./styles.css";
import styled from "styled-components";
const Button = styled.button`
font-family: "Work Sans", sans-serif;
font-size: 14px;
font-weight: 600;
color: #ffffff;
line-height: 16px;
background: ${(props) => (props.background ? props.background : "#00D2AD")};
transition: all 0.4s ease-out;
transition: all 0.4s ease-out;
padding: 14px 24px;
outline: none;
text-align: center;
display: inline-block;
border: none;
cursor: pointer;
border-radius: 4px;
`;
export default function App() {
return (
<div className="App">
<Button>Default Button </Button>
<br />
<br />
<Button background={"gray"}>Custom Button</Button>
</div>
);
}

React re-use a component with different style and layout

I'm new to styling in React. I tried CSS modules and styled components but I'm not able to change layout and styles.
The goal is to have a group of buttons to display as flex on the main page and as an inline with different style attributes in another page by re-using the HomeButtons.js component.
HomeButtons.js is the home page and it has a map() function looping through a button called ButtonCategory.js.
HomeButtons.js renders the map() inside a styled using CSS modules file. ButtonCategory is styled with a CSS modules file as well.
HomeButtons.js is then returned inside a in another class Component called CardsCategory.js. It is in this component that I'm trying to change the display and styl... With a styled Component on the I can show a border but the display attribute doesn't works.With CardsCategory.module.css I can't change the display either...
Not sure what to do... How to change the layout of the re-used component and the style of its nested button component ?
Any feedback is welcome!
HomeButtons.js
import React, { Component } from 'react'
import classes from './HomeButtons.module.css';
import ButtonCategory from '../../components/ButtonCategory/ButtonCategory'
class HomeButtons extends Component {
handleClick = (buttonValue) => {
buttonValue = buttonValue.slice(0, 3).toLowerCase();
this.props.history.push("/" + buttonValue);
};
render() {
const allCategoriesButtons = ["Physics", "Chemistry", "Medicine", "Literature", "Peace", "Economics"];
const allCatMap = allCategoriesButtons.map(button =>
< ButtonCategory
key={button.toString()}
value={button}
name={button}
onClick={e => this.handleClick(e.target.value)}
/>
)
return (
<div>
<div className={classes.container__section}>
{allCatMap}
</div >
</div>
)
}
}
export default HomeButtons;
HomeButtons.module.css
.container__section {
display: flex;
flex-flow: row wrap;
margin: auto;
align-items: center;
justify-content: space-around;
}
ButtonCategory
import React from 'react'
import classes from './ButtonCategory.module.css';
function buttonCategory(props) {
return (
<button
className={classes.b}
name={props.name}
onClick={props.onClick}
value={props.value}
>
{props.name}
</button>
)
}
export default buttonCategory;
ButtonCategory.module.css
opacity: 0.5;
color: red;
font-size: 2em;
margin: 10px 20px 10px 20px;
flex: 1 400px;
height: 3em;
}
CardsCategory
import React, { Component } from 'react';
import axios from 'axios';
import classes from './CardsCategory.module.css';
import HomeButtons from "../HomeButtons/HomeButtons"
import styled from 'styled-components';
const StyledDiv = styled.div`
border: 10px solid orange;
//display: inline; //NOT working
`
class Cards extends Component {
render() {
return (
<div>
<StyledDiv>
<HomeButtons className={classes.test}/>
</StyledDiv>
</div>
)
}
}
export default Cards;
CardsCategory.module.css
.test {
display: inline;
}
You can send styles thru the props and in the component set them as your styles ex.
<MyComponent textAlign='center' ...>
in MyComponent component
<div style={{textAlign: this.props.textAlign}}>
...
</div>
or send whole styles as objects ex.
render(){
const stl = {textAlign: 'center',width:'500px'};
return(
<MyComponent wholeStyle={stl}/>
)
}
and in MyComponent
<div style={this.props.wholeStyle}>
...
</div>
They are 3 ways you can style through props
You can pass an entire style object
Eg:
<MappedComponent style={'display':'flex','alignItems':'center'} />
In the mapped component
Function MappedComponent ({style}){
return (
What's popaining !
);
}
You can style by passing in the specific style you want
Eg:
<MappedComponent textAlign={'center'} />
In the mapped component
Function MappedComponent ({textAlign}){
return (
What's popaining !
);
}
The third way you can style is by defining styles in a CSS file and just passing in the class name
Eg:
<MappedComponent className={''flex-button-style'} />
In the mapped component
Function MappedComponent ({className}){
return (
What's popaining !
);
}
Pick what works best for you and stay consistent with it :) .

In React, styled component's flex not working

I trying to work with styled-components. However now, I 'm using "flex" for responsive design, But I can't figure it out.
CSS of styled-components doesn't work. I don't see those styles on my website
Below is outline of my styling
import TagsInput from 'react-tagsinput';
import PostTypeSelector from './PostTypeSelector';
import styled from 'styled-components';
import PostMarkdown from './PostMarkdown';
import PostSubmit from './PostSubmit';
// const StyledPostSubmit = styled(PostSubmit)`
// `;
// const StyledTagsInput = styled(TagsInput)`
// `;
const StyledPostTypeSelector = styled(PostTypeSelector)`
background-color: gray;
flex: 1 0;
`;
const StyledPostForm = styled(PostForm)`
flex: 9 0;
`;
const StyledPostMarkdown = styled(PostMarkdown)`
flex: 10 0;
border-left: 1px solid #222222;
`;
and I adjust like this
render() {
return (
<div className="posting">
<div className="plain-post-form-0">
<div className="plain-post-form-1">
<div style={{
display: 'flex',
flexDirection:'row',
width: '800px'
}}
className="plain-post-form-2"
>
<StyledPostForm
onSave={this.handleSave}
post={this.initValue()}
/>
<StyledPostTypeSelector
/>
<StyledPostMarkdown
post={this.state}
/>
</div>
<TagsInput
value={this.state.tags}
onChange={this.handleTagsChange}
/>
<PostSubmit
data={this.handleCommit}
target={post}
method="post"
value="Commit"
/>
</div>
</div>
</div>
);
}
As stated in the docs:
If you use the styled(MyComponent) notation and MyComponent does not render the passed-in className prop, then no styles will be applied.
// For this to work
const StyledPostForm = styled(PostForm)`
flex: 9 0;
`;
// You need to apply the className prop to component's top node (Container/Parent)
const PostForm = ({ className }) => (
<Container className={className}>...</Container>
)

Categories