I have a basic Card.
I want the image to change its src when I mouseover on the card.
I can change the image when I mouseover on the <img/> tag itself like so :
<img src={item.iconUrl}
onMouseOver={e => (e.currentTarget.src = item.iconHoverUrl)}
onMouseOut={e => (e.currentTarget.src = item.iconHoverUrl)}
className="mr-3 avatar-lg rounded" alt="app_icon"
/>
But I don't find any way to reference this image's src when I'm out of it's scope.
I tried setting the content of src into a variable and changing it's value on the card's mouseover but that won't trigger an update of the src of the image so it doesn't work either.
Here is the code of the component if it helps :
<Card className="app-hover" style={{ marginTop: '10px', height: '92%', overflow: 'hidden' }}>
<CardBody className="p-3">
<Media>
<img src={item.iconUrl}
onMouseOver={e => (e.currentTarget.src = item.iconHoverUrl)}
onMouseOut={e => (e.currentTarget.src = item.iconHoverUrl)}
className="mr-3 avatar-lg rounded" alt="app_icon" />
<Media body>
<Row style={{ marginLeft: '4px', marginTop: '15px' }}>
<h5 className="mt-1 mb-0">{this.props.i18n.language === 'en' ? item.title : item.titleFR}</h5>
</Row>
</Media>
</Media>
<Row>
<Col lg={6}>
<Media>
<CreditCard className="icon-dual align-self-center mr-2"></CreditCard>
<Media body>
<h5 className="mt-2 pt-1 font-size-16">{this.props.i18n.language === 'en' ? 'Not Owned' : 'Non-Acquis'}</h5>
</Media>
</Media>
</Col>
<Col lg={6}>
<Media>
<Users className="icon-dual align-self-center mr-2"></Users>
<Media body>
<h5 className="mt-2 pt-1 font-size-16">
{
item.stats ? item.stats.users : ''
}
</h5>
</Media>
</Media>
</Col>
</Row>
<Row className="mt-2 border-top pt-2" style={{ paddingLeft: '8px', paddingRight: '8px' }}>
<p className="text-muted">{this.props.i18n.language === 'en' ? item.shortDescription : item.shortDescriptionFR}</p>
</Row>
</CardBody>
Is it possible to do it the way I have it setup? As you can obviously see from the code, the image is fetched from an api and always changing so I can't simply hardcode the animation in CSS.
You should not try to change the DOM "directly", instead you should call a function that mutate the state and use the new icon from the state itself. Let me explain with an example:
const [icon, setIcon] = useState("");
const onMouseOver = () => setIcon("the-over-icon");
const onMouseOut = () => setIcon("the-not-over-icon");
// ...
<Card onMouseOver={onMouseOver} onMouseOut={onMouseOut}>
<img src={icon} />
</Card>
I will extract img into functional component. In Typescript something like.
import React from "react";
import { useState } from "react";
interface IMyImgProps{
iconUrl: string;
iconHoverUrl: string;
}
export const MyImg: React.FunctionComponent<IMyImgProps> = props => {
const [icon, setIcon] = useState(props.iconUrl);
const onMouseOver = () => setIcon(props.iconHoverUrl);
const onMouseOut = () => setIcon(props.iconUrl);
return <img src={icon} onMouseOver={onMouseOver} onMouseOut={onMouseOut} />
}
Related
I'm trying to change the borderColor on this Select Component from Native base.
Here is an image of the default color and the focused color:
The border is black by default. I already tried with borderColor="" and none/unset but it isn't changing the color.
How can I change the default and active border color?
The code is here..
useState,
} from 'react';
import {
Box,
Select,
CheckIcon,
} from 'native-base';
function Dropdown({
options = [],
placeholder,
backgroundColor,
className,
onChange = () => {},
}) {
const [value, setValue] = useState('');
return (
<Box>
<Box width="3/4" maxWidth="300">
<Select
className={className}
onChange={onChange}
minWidth="200"
selectedValue={value}
accessibilityLabel="Choose Service"
placeholder={placeholder}
backgroundColor={backgroundColor}
_selectedItem={{
bg: 'teal.600',
endIcon: <CheckIcon size="5" />,
}}
_focus={{
bg: 'white',
}}
marginTop={1}
onValueChange={(itemValue) => setValue(itemValue)}
>
{options.map((option) => (
<Select.Item
label={option.label}
value={option.value}
key={option.value}
style={{ display: 'flex', flexDirection: 'column', padding: 5 }}
/>
))}
</Select>
</Box>
</Box>
);
}```
You can use borderColor to specify border color and borderWidth to specify border width. To specify border color for focused inside _focus.
const Example = () => {
let [service, setService] = React.useState('');
return (
<Center>
<Box w="3/4" maxW="300">
<Select
_focus={{ borderColor: 'yellow.500' }}
borderColor="red.500"
selectedValue={service}
minWidth="200"
accessibilityLabel="Choose Service"
placeholder="Choose Service"
_selectedItem={{
bg: 'teal.600',
endIcon: <CheckIcon size="5" />,
}}
mt={1}
onValueChange={(itemValue) => setService(itemValue)}
>
<Select.Item label="UX Research" value="ux" />
<Select.Item label="Web Development" value="web" />
<Select.Item label="Cross Platform Development" value="cross" />
<Select.Item label="UI Designing" value="ui" />
<Select.Item label="Backend Development" value="backend" />
</Select>
</Box>
</Center>
);
};
I have an imagelist and I want to render buttons below the images
This is my code so far;
export const Media = (stuff) => {
const { medias } = stuff;
console.log(medias);
const classes = useStyles();
return (
<div className={classes.root}>
<ImageList className={classes.imageList} gap={2} cols={3}>
{medias.map((media) => (
<ImageListItem key={media.cover_photo_url}>
<img
src={media.cover_photo_url}
className={classes.image}
style={{ borderRadius: "15px" }}
/>
<PlayArrowIcon className={classes.overlay} />
<ImageListItemBar subtitle={<LinkIcon></LinkIcon>} position="below"/>
</ImageListItem>
))}
</ImageList>
{medias.map((item) => (
<Buttons item={item} />
))}
</div>
);
};
I can display the buttons with the map function below however it doesnt scroll with the image that is relative with it horizontally
how can i make the buttons stick together with the images?
Thanks
you can try using <Box> like this
import Box from '#material-ui/core/Box';
<Box>
<ImageListItem key={media.cover_photo_url}>
<img
src={media.cover_photo_url}
className={classes.image}
style={{ borderRadius: "15px" }}
/>
<PlayArrowIcon className={classes.overlay} />
<ImageListItemBar subtitle={<LinkIcon></LinkIcon>} position="below"/>
</ImageListItem>
<Buttons item={item} />
</Box>
Just Remove Second loop for buttons and bring button tag in first loop and wrapper ImageListItem and Button with a div
Replace this,
{medias.map((media) => (
<ImageListItem key={media.cover_photo_url}>
<img
src={media.cover_photo_url}
className={classes.image}
style={{ borderRadius: "15px" }}
/>
<PlayArrowIcon className={classes.overlay} />
<ImageListItemBar subtitle={<LinkIcon></LinkIcon>} position="below"/>
</ImageListItem>
))}
</ImageList>
{medias.map((item) => (
<Buttons item={item} />
))}
With this,
{medias.map((media) => (
<Box>
<ImageListItem key={media.cover_photo_url}>
<img
src={media.cover_photo_url}
className={classes.image}
style={{ borderRadius: "15px" }}
/>
<PlayArrowIcon className={classes.overlay} />
<ImageListItemBar subtitle={<LinkIcon></LinkIcon>} position="below"/>
</ImageListItem>
<Buttons item={media} />
</Box>
))}
You can Import the Box by using this
import Box from '#material-ui/core/Box';
I have a react Card.
I want to bring the image on the card to the right-side of card and it should also be parellel to the Name Pankaj Rout, and should be responsive.
This is what I have tried so far,
var userMap = [
{name: "Pankaj Rout", email: "pankaj.rout#somedomain.com"}
]
userData.map((data) => {
return (
<div key={data.email}>
<Card style={cardStyle}>
<Card.Body>
<div class="col-sm-6 text-right">
<img
className={classes.img}
style={cardImgStyle}
src="https://www.w3schools.com/howto/img_avatar.png"
alt="sans"
/>
</div>
<Card.Title> {data.name} </Card.Title>
<Card.Subtitle className="mb-2 text-muted">
General Manager
</Card.Subtitle>
<Card.Text> {data.email} </Card.Text>
<Button> Delete </Button>
<Button> Email </Button>
<Button> Chat </Button>
</Card.Body>
</Card>
</div>
);
classes is used from withStyles hook
const useStyles = (theme) => ({
img: {
justifyContent: 'right',
}
});
following style is referring to cardImgStyle
const cardImgStyle = {
width: "30%",
height: "30%",
borderRadius: "50%",
display: "flex",
flexWrap: "wrap",
};
Could anyone please point out what is wrong here?
Thanks!!
justifyContent : 'space-beetwin' ;
or
for img :
float :' right';
I have a 4 text fields which are meant to be used to type in a 4 digit code sent to the phone. How can I automatically change to the next field if a number is written and for it not to take anything apart from numbers
Ill attach a picture along with my code base
// flow
import React, { useRef } from 'react';
import { signup } from '../../assets/images';
import FormDiv from '../shared/Sign-in-div';
import ImageDiv from '../shared/Image-div';
import { Nunito32, Nunito20 } from '../shared/nunito/nunito';
import ImageContainer from '../shared/image-container';
import OtpField from '../shared/otp-field';
import PinkButton from '../shared/button-color-pink';
let [fieldOne, fieldTwo, fieldThree, fieldFour] = useRef(null);
const onChange = field => {
field.focus();
};
const SignUpVerification = () => (
<div style={{ display: 'flex' }}>
<FormDiv style={{ textAlign: 'center' }}>
<Nunito32
style={{
display: 'inline-block',
textAlign: 'center',
marginRight: 236,
marginLeft: 200,
}}
>
Verify your mobile number by entering the code we sent you
</Nunito32>
<div style={{ flexDirection: 'row' }}>
<OtpField
ref={input => {
fieldOne = input;
}}
style={{ marginRight: 10.5 }}
onChange={() => onChange(fieldTwo)}
/>
<OtpField
ref={input => {
fieldTwo = input;
}}
onChange={() => onChange(fieldThree)}
style={{ marginRight: 10.5 }}
/>
<OtpField
ref={input => {
fieldThree = input;
}}
onChange={() => onChange(fieldFour)}
style={{ marginRight: 10.5 }}
/>
<OtpField
ref={input => {
fieldFour = input;
}}
style={{ marginRight: 10.5 }}
/>
</div>
<PinkButton style={{ marginTop: 75 }}>Continue</PinkButton>
<Nunito20>Send again</Nunito20>
</FormDiv>
<ImageContainer>
<ImageDiv bg={signup} src={signup} alt="logo" />
</ImageContainer>
</div>
);
export default SignUpVerification;
It now gives me 2 errors that fieldOne is created but not used and ×
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
How about re-render when the state you change?
Handling focus is good task for Refs in React. So idea will be to have refs for input fields and in onChange event handler check if user typed 3 digits and turn focus to next input.
I have created demo on codesandbox to showcase how it works
Since you are making use of React JS, you can go forward with React Refs and the DOM where you can select the nodes and handle the focus pragmatically. This is a sample implementation. Find the implementation here.
class App extends React.Component{
componentDidMount(){
this.fieldOne.focus();
}
onChange(field) {
field.focus();
}
render() {
return(
<div>
<input
onChange={() => this.onChange(this.fieldTwo)}
ref={(input) => { this.fieldOne = input; }}
placeholder="First Field"
/>
<input
onChange={() => this.onChange(this.fieldThree)}
ref={(input) => { this.fieldTwo = input; }}
placeholder="Second Field"
/>
<input
onChange={() => this.onChange(this.fieldFour)}
ref={(input) => { this.fieldThree = input; }}
placeholder="Third Field"
/>
<input
ref={(input) => { this.fieldFour = input; }}
placeholder="Fourth Field"
/>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.1/react-dom.min.js"></script>
<div class="container-fluid" id="main">
<div class="row">
<div class="col-xs-12">
<div id="root"></div>
</div>
</div>
</div>
I am wishing to display card's which hold a Bootstrap badge at the top of each card. I would like to conditionally change the colour of the badge depending on status of the pet.
render() {
const isAdmin = true;
const post = this.props.post;
const id = this.props.post.post_ID;
console.log(post);
return (
<div>
<Card id="card-main" style={{ width: '18rem', margin: '12px' }}>
<span class="badge badge-secondary">{post.petStatus}</span>
<Card.Img id="card-img-top" variant="top" src={post.img_path} />
<Card.Body>
<Card.Title>{post.pet_name}</Card.Title>
<Card.Text id="PetName">
<strong>{post.petName} </strong>
</Card.Text>
<Card.Text id="content">
{post.content}
</Card.Text>
<Card.Text>
<strong>Posted By: </strong>{post.name}
</Card.Text>
<Card.Text
<strong>Posted: </strong>{post.postedOn}
</Card.Text>
</Card>
Depending on the number of colors your need, you could either do it inline:
<Card id="card-main" style={{ width: '18rem', margin: '12px' }}>
<span class="badge badge-secondary" style={{color: post.petStatus === "adopted" ? "blue" : "red"}}>{post.petStatus}</span>
... or if you need several colors probably better to write a helper that returns a style based on the status:
getStyleForStatus = (status)=>{
let statusColor
switch (status){
case "adopted":
statusColor = "blue"
break;
case "lost":
statusColor = "red"
break;
default:
//
return {color:statusColor}
}
}
render() {
const isAdmin = true;
const post = this.props.post;
const id = this.props.post.post_ID;
console.log(post);
return (
<div>
<Card id="card-main" style={{ width: '18rem', margin: '12px' }}>
<span class="badge badge-secondary" style={getStyleForStatus(post.petStatus)}>{post.petStatus}</span>
{/* ... */}
</Card>