Style the 'choose file' button - reactjs

I have a simple way to hide the button within a container div so that it is invisible. However, I want the cursor to be a crosshair over the whole thing, but I don't know how to change the cursor so it is a crosshair when it is highlighting it. As you can observe, the cursor switches to its default when the choose file button is hovered. Here is my code, and a link to the sandbox: https://codesandbox.io/s/zen-elgamal-mk059?file=/src/App.js
import React from "react";
import styled from "styled-components";
import "./styles.css";
const MyButton = styled.div`
position: absolute;
width: 50px;
height: 50px;
background-color: red;
cursor: crosshair;
`;
const StyledForm = styled.form`
position: absolute;
width: 100%;
height: 100%;
cursor: crosshair;
`;
const StyledInput = styled.input`
width: 100%;
height: 100%;
box-sizing: border-box;
cursor: crosshair;
background-color: pink;
`;
export default function App() {
return (
<div className="App">
<MyButton>
<StyledForm>
<StyledInput type="file" />
</StyledForm>
</MyButton>
</div>
);
}

the problem is you are using default input button.You should replace with a custom.
Here is my solition.
https://codesandbox.io/s/vigilant-pond-tncxt?file=/src/App.js

Related

React. Two buttons in a component but only one button works

I am practicing React basics.
I have a component mapped from an array of objects and it shows twice in my website but only on the second time the button works. the first button does not seem to be recognised.
Can someone explain why please? I can't find a reason for this but I am sure it is something obvious I am missing
A link to sandbox
App.js
import MainComponent from "./components/MainComponent";
function App() {
return (
<div>
<MainComponent />
</div>
);
}
export default App;
MainComponent.js
import React from "react";
import TextItem from "./TextItem";
const text = [
{
image:
"https://pbs.twimg.com/profile_images/626298192418607105/4KBKHQWi_400x400.jpg",
title: "This is a whale",
subtitle: "It is a large mammal",
price: "£ 167.87 + VAT",
uom: "per Unit",
},
{
image:
"https://news.artnet.com/app/news-upload/2019/01/Cat-Photog-Feat-256x256.jpg",
title: "This is a cat",
subtitle: "It is a small mammal",
price: "£ 17.87 + VAT",
uom: "per Unit",
},
];
const MainComponent = () => {
return (
<div>
{text.map((eachText, i) => (
<TextItem
key={i}
image={eachText.image}
title={eachText.title}
subtitle={eachText.subtitle}
price={eachText.price}
uom={eachText.uom}
/>
))}
</div>
);
};
export default MainComponent;
TextItem.js
import React from "react";
import styled from "styled-components";
import Card from "../UI/Card";
const TextItem = (props) => {
const onClickHandler = () => {
console.log("clicked");
};
return (
<Card>
<DivFlex>
<ImgDiv>
<img src={props.image} alt={"a whale"} />
</ImgDiv>
<TitleDiv>
<h1>{props.title}</h1>
<h3>{props.subtitle}</h3>
</TitleDiv>
<PriceDiv>
<h2>{props.price}</h2>
<h2>{props.uom}</h2>
</PriceDiv>
<EditDiv>
<Button onClick={onClickHandler}>Edit this</Button>
</EditDiv>
</DivFlex>
</Card>
);
};
const DivFlex = styled.div`
display: flex;
justify-content: center;
align-items: center;
width: 800px;
height: 600px;
`;
const ImgDiv = styled.div`
width: 90px;
height: 90px;
margin-right: 3%;
img {
max-width: 100%;
height: 100%;
border-radius: 6px;
}
`;
const TitleDiv = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
width: 30%;
margin-right: 3%;
`;
const PriceDiv = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-end;
width: 20%;
margin-right: 3%;
`;
const EditDiv = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
width: auto;
margin-left: 3%;
`;
const Button = styled.div`
outline: none;
border: none;
background: maroon;
color: white;
padding: 1.2rem 1.8rem;
font-size: 22px;
border-radius: 8px;
cursor: pointer;
`;
export default TextItem;
This is happening due to the conflicting heights of Card and DivFlex. The Card has an height of 140px but its child DivFlex has a height of 600px. So, the next item is basically overlapping the previous item and hence you are not able to click the first button. You can observe the same behaviour if you had any number of items. Only the last item would be clickable due to it overlapping on top of previous item.
One way to fix this is to remove the height from Card component and change the height of DivFlex to 140px instead.
PS: It didn't happen in the replica sandbox because you didn't use the Card component there and used a regular div which by default has a height of auto

Flexbox Container with Child in it with position absolute

I'm new to React, and I'm currently building a slideshow on my website. Basically, I have a left arrow, the slide content, then the right arrow in my flexbox for my slideshow. However, to make my arrows on the edges of the screen I needed to use position absolute, which messes up my flexbox container. I figured out that absolutely positioned child items don't count in the flexbox of the parent, but is there a way around that? As of now, my image is overlapping with the left arrow. Thanks, and sorry if this is poorly written since I'm very new to this all. Code will be below.
Image: [1]: https://i.stack.imgur.com/PkL3Z.jpg
import { ArrowBackIosOutlined, ArrowForwardIosOutlined } from '#material-ui/icons'
import React from 'react'
import styled from 'styled-components'
import grocery from '../assets/grocery.png'
const Container = styled.div`
width: 100%;
height: 100vh;
display: flex;
position: relative;
`
const Arrow = styled.div`
width: 50px;
height: 50px;
background-color: #fff7f7;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
bottom: 0;
left: ${props => props.direction === "left" && "10px"};
right: ${props => props.direction === "right" && "10px"};
margin: auto;
cursor: pointer;
opacity: 0.5;
`
const Wrapper = styled.div`
height: 100%;
`
const Slide = styled.div`
width; 100vw;
height: 100vh;
display: flex;
align-items: center;
`
const ImageContainer = styled.div`
height: 100%;
flex: 1;
margin-top: 50px;
`
const Image = styled.img`
height: 50%;
`
const InfoContainer = styled.div`
flex: 1;
`
const Slider = () => {
return (
<Container>
<Arrow direction="left">
<ArrowBackIosOutlined/>
</Arrow>
<Wrapper>
<Slide>
<ImageContainer>
<Image src={https://images.unsplash.com/photo-1481349518771-20055b2a7b24?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8M3x8cmFuZG9tfGVufDB8fDB8fA%3D%3D&w=1000&q=80}/>
</ImageContainer>
</Slide>
</Wrapper>
<Arrow direction="right">
<ArrowForwardIosOutlined/>
</Arrow>
</Container>
)
}
export default Slider

Styled Component underline hover

How would you translate this kind of psuedo effect to a styled component. E.g the exact same underline, but all stored within one const CSS in JS effect.
I'd like to build the following, but not sure how to write this into a styled comp
a::after {
content: "";
display: block;
margin-top: 10px;
margin-left: auto;
margin-right: auto;
height: 2px;
width: 0px;
background-color: tomato;
}
I've created a codesandbox at https://codesandbox.io/s/ecstatic-leaf-oj1my?file=/src/App.js
Given below is the code for completeness. I've added a hover so you can easily see that the styles are being applied. Try changing the height in your pseudo element to see that your styles for the pseudo element are being applied too.
import "./styles.css";
import styled from "styled-components";
const StyledAchor = styled.a`
color: blue;
&:hover {
color: white;
}
&::after {
content: "";
display: block;
margin-top: 10px;
margin-left: auto;
margin-right: auto;
/* try changing the height to see the after pseudo element is being applied */
height: 20px;
width: 0px;
background-color: tomato;
}
`;
export default function App() {
return (
<div className="App">
<StyledAchor href="/">styled anchor tag</StyledAchor>
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}

How to Desktop View, Tablet View ,Mobile view change inside a browser ReactJS

I am new to Reactjs . How to add 3 views inside a browser,by automatically change view.
Reference Page Link
You can wrap all your content with a div and control the width of that div.
// App.js
import { useState } from 'react';
import './App.css';
function App() {
const [state, setState] = useState('desktop');
return (
<div className="App">
<button onClick={() => setState('desktop')}>Desktop</button>
<button onClick={() => setState('tablet')}>Tablet</button>
<button onClick={() => setState('phone')}>Phone</button>
<div className={`container ${state}`}>Your content here</div>
</div>
);
}
export default App;
/*App.css*/
.App {
height: 100%;
background-image: -webkit-linear-gradient(0deg, #766dff 0%, #88f3ff 100%);
}
/* General styling */
button {
padding: 0.5rem;
margin: 1rem;
border-radius: 10px;
cursor: pointer;
border: none;
}
.container {
/* General styling */
background-color: whitesmoke;
padding: 1rem;
border-radius: 5px;
margin-top: 1rem;
transition: all 1s;
/* Center the container */
margin-left: auto;
margin-right: auto;
}
.desktop {
width: 90%;
}
.tablet {
width: 768px;
}
.phone {
width: 480px;
}
/* index.css */
/* To make full width and height */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body,
#root {
height: 100%;
}
The above answer is correct. You can simply give a width to the main container to 100% and place your other container with other elements inside of it, also specify width using #mediaqueries(" https://www.w3schools.com/css/css_rwd_mediaqueries.asp "). This way, you can control the elements inside the main container. I can say for sure that you need to try it by yourself and see how everything works, use devtools(there is toogle device toolbar).

Styled-components extends props

I have a ready button like this , These are the features I want every button to have.
If I send props for the icon, I don't want the icon to be created, if I don't, I don't want it to be created.
import Icon from 'components/icons/Icon';
import styled from 'styled-components';
const Button = styled.button`
border-radius: 8px;
color: white;
cursor: pointer;
outline: none;
border: none;
display: flex;
font-family: 'DM Sans', sans-serif;
font-weight: 700;
`;
const DefaultButton = ({ name, children }) => {
return (
<Button>
{name && <Icon name={name}></Icon>}
{children}
</Button>
);
};
export default DefaultButton;
I have a button component that I have customized like this.
I want it to inherit its properties from the default button.
But Primary's features do not appear on my button.
I wonder what should I fix, thanks friend
import styled from 'styled-components';
import { sizes } from 'constants/components/button';
import { colors } from 'theme';
import DefaultButton from './DefaultButton';
const PrimaryButton = styled(DefaultButton)`
padding: ${({ size }) => sizes[size]} 48px;
background-color: ${colors.primary.color};
font-size: 14px;
font-style: bold;
&:focus {
border: 1px solid #ffffff;
box-sizing: border-box;
box-shadow: 0px 0px 0px 3px rgba(24, 207, 152, 1);
}
&:hover {
background-color: ${colors.primary.pressed};
box-shadow: 0px 14px 24px rgba(23, 207, 151, 0.3);
color: white;
}
&:disabled {
background-color: ${colors.primary.disabled};
cursor: not-allowed;
pointer-events: none;
color: white;
}
`;
export default PrimaryButton;
This is how I use my component and I want it to be like this
<PrimaryButton size="md" name="test">
Sign in
</PrimaryButton>
If you want to extend/override the styles of another component, you need to pass down the className prop, as mentioned in the docs.
The styled method works perfectly on all of your own or any third-party component, as long as they attach the passed className prop to a DOM element.
const DefaultButton = ({ name, children, className }) => {
return (
<Button className={className}>
{name && <Icon name={name}></Icon>}
{children}
</Button>
);
};
I find #svrbst solution very effective. I extended it to add other dependencies as shown is the question and it works fine. Here is the forked codesandbox

Resources