hey I have designed a rectangle using css and it displays a text inside of it , How can I convert this whole component as a means to navigate to some other url (i have tried using the Link from reactrouterDOM but it changed the shape and also an underline appeared just below the text, which defeated the whole point of it not looking like a link text ).
Any Approach Would be helpful as I am quite new to React.Thanks!
If you want to use Link from react-router:
<Link to="/url" style={{
textDecoration: 'none',
color: 'inherit',
display: 'inline-block',
}}>
<Rectangle/>
</Link>
If you just want to handle onClick in rectangle:
export const Rectangle = (props) => (
<div onClick={props.onClick}>whatever</div>
);
and then use it as:
<Rectangle onClick={() => console.log('whatever')}/>
PS: https://reactjs.org/docs/handling-events.html
Related
I am implementing Paper from Material UI: https://mui.com/components/paper/
And here is the code I have written so far:
<Paper className="modal" elevation={3}>
{..Content..}
</Paper>
The current UI makes it open a special pane which closes only when I click on area outside of it. I want to add a close button to close the Paper. Is it possible to add a custom onClose action on it?
Edit: Here is a codesandbox that I have replicated: https://codesandbox.io/s/black-surf-r1yz87?file=/src/App.js
Paper is just a surface to render components on, it does not support any functionality. For this use case, a state variable can be used to hide and unhide the Paper component. You may make it a reusable component.
const [shouldShowPaper, setShouldShowPaper] = useState(true);
...
{
shouldShowPaper &&
<Paper elevation={props.elevation} style={{position: "relative"}}>
<button
style={{position:"absolute", top: "10px", right: "10px"}}
onClick={() => setShouldShowPaper(false)}
>
X
</button>
{props.children}
</Paper>
}
You may toggle classes to show transitions instead of abrupt removal of the paper component.
I have the following tag with a hard-coded color:
<p style={{ color: '#646464' }}>
I want to use a LESS variable that I've defined instead, let's called it #tertiary-col, how would I use this variable? <p style={{ color: '#tertiary-col' }}> doesn't seem to work
It is possible to use native var() to do this.
By placing the variable in :root then it becomes available anywhere you need to use it.
You would do --tertiary-col: #tertiary-col;, but for the purposes of the snippet I have put in an actual hex value.
:root {
--tertiary-col: #tertiary-col; /* this is what you would do */
--tertiary-col: #646464; /* #tertiary-col; */
}
<p style="color: var(--tertiary-col)">Some text</p>
Here is an excellent tutorial on css variables: https://codepen.io/abcretrograde/full/xaKVNx/
You cannot use variables from CSS-precompilers like LESS inside of your JSX. You can either use JavaScript variables like
const redColor = "#FF0000";
<p style={{ color: redColor }}
Or give it a className and let your CSS handle the rest.
Another option would be to add a loader like less-vars-to-js to map your LESS variables (I'm assuming you mean LESS as you're using #) to JavaScript.
And another option would be to use native CSS variables as other answers suggested, you can use these variables within your JavaScript, the downside on this is that they aren't supported by all browsers (yet).
For using native css variables in React:
Let's say you want to toggle between light and dark themes for any text nodes in a certain element:
const LightDarkSpan = ({ children }) => (
<span style={{
color: 'var(--text-color, black)'
}}>
{children}
</span>
);
Then, any parent can set that variable, and it effectively acts as context to any child element that explicitly chooses to use that specific CSS variable:
// rendered
<div style={{
backgroundColor: 'black',
'--text-color': 'white'
}}>
<article>
<LightDarkSpan>testing</LightDarkSpan>
</article>
</div>
Reference
So I'm new to React (and JavaScript too for that matter). I'm creating an App using react native and currently trying to style my popup menu. (which looks like this: Popup menu image)
I want to change the style of the options (make the font size bigger and space them out and change the font color too). My code looks something like this:
<MenuProvider>
<Menu >
<MenuTrigger>
<Image
style={styles.menucontainer}
resizeMode="contain"
source={require('../assets/icon_more.png')}>
</Image>
</MenuTrigger>
<MenuOptions optionsContainerStyle={styles.optionsstyle}>
<MenuOption text= 'About' />
<MenuOption text= 'Help & Feedback'/>
<MenuOption text= 'Sign Out'/>
</MenuOptions>
</Menu>
</MenuProvider>
After checking
https://github.com/instea/react-native-popup-menu/blob/master/src/MenuOption.js
I found a prop customStyles. Just like I passed a styling object for MenuOptions as prop optionContainerStyle, I tried passing customStyles for MenuOption but that produced an error:
In this environment the sources for assign MUST be an object. This error is a performance optimization and not spec compliant.
Here is my styles code:
const styles = StyleSheet.create({
optionsstyle:{
marginTop: height*32/dev_dimension.h,
marginLeft: width*184/dev_dimension.w,
backgroundColor: '#fafafa',
width: width*168/dev_dimension.w,
height: height*160/dev_dimension.h,
flexDirection: 'row',
flex: 1,
justifyContent: 'space-between',
},
});
Can anyone tell what I'm doing wrong?
According to documentation the optionsContainerStyle are deprecated and I am not sure if they work properly. Try to use customStyles props instead as seen in StylingExample where you can find full example.
The thing is that customStyles is map of styles for different parts. Something like
<MenuOptions customStyles={{optionWrapper: { padding: 5}, optionText: styles.text}}>
According to React Material-UI docs, I have a prop hoveredStyle to work with: http://www.material-ui.com/#/components/icon-button
I want to use IconButton for two purposes:
Utilize its tooltip prop for accessibility
I can wrap Material-UI svg icons directly
However, I don't want the cursor to change to a pointer when I hover (which is default behavior I believe), so I changed it like so.
import DeleteIcon from 'material-ui/svg-icons/action/delete
const hoveredStyle = {
cursor: 'initial'
}
render() {
return (
<IconButton tooltip="Description here" hoveredStyle={hoveredStyle}>
<DeleteIcon />
</IconButton>
)
}
This works fine, except that the split millisecond that I enter hover mode on the icon, I still see the default hand pointer before it gets set to the normal mouse pointer. How do I approach this?
I just tested adding a cursor: default to the style of both IconButton and DeleteIcon and it seems to have the functionality you want. (No pointer cursor on hover.)
const noPointer = {cursor: 'default'};
return (
<div>
<IconButton tooltip="Description here" style={noPointer}>
<DeleteIcon style={noPointer} />
</IconButton>
</div>
);
Some notes for people stumbling upon this thread. If you are having a problem with hover styles for an icon if you are using Material-ui you might have forgot something.
In my case I used a <KeyboardArrowLeft/> and wrapped it in a <Tooltip/>. I could not get hover styles in there at all including a simple hand "cursor". I had to wrap the icon with <IconButton>. It is in that element where you can pass styles.
While the example that was provided before as the "accepted answer" does solve the initial problem, it is not production level.
If you are using reactjs you will need to import the following into your component, switch with your respective icon
import Tooltip from '#material-ui/core/Tooltip';
import IconButton from '#material-ui/core/IconButton';
import KeyboardArrowLeft from '#material-ui/icons/KeyboardArrowLeft';
In the icon wrap as follows
<Tooltip title="">
<IconButton
aria-label=""
style={componentStyle.iconBack}
>
<KeyboardArrowLeft
style={componentStyle.eventHeadingBack}
onClick={}
/>
</IconButton>
</Tooltip>
In the Tooltip, give it a title of what the user should expect when clicking the button.
In the IconButton, add some description for aria (screen readers) like "back to home page". In the style, use a class. You will have a const that you can use for that component you are working on, then give the classname for the actual element a descriptive title. This is where you can control the cursor and hover actions.
In the actual icon, give it a class so you can do things like change color.
Now you will need to style the component, name it however you want but ideally according to the components purpose.
const componentStyle = {
container: {
display: 'flex',
width: '100%',
height: '100vh',
backgroundColor: '#212121',
},
iconBack: {
cursor: 'crosshair'
},
eventHeadingBack: {
color: '#fff',
marginRight: '16px'
}
}
Is there a way I can add ripple effect to MUI Card component on click.
And I would also like to know, is it possible to make ripple effect to come on top of the content of Card component, rather that it showing as background.
I noticed that TouchRipple has been moved out of the internal directory.
It's now available in the ButtonBase folder.
Here is how I was able to add ripple effect by using the ButtonBase component -
Basically, you wrap your component, let's say <Card> inside the <ButtonBase> like so, and the ButtonBase takes care of the TouchRipple setting up for you -
<ButtonBase>
<Card>
....
</Card>
</ButtonBase>
Here is a Codesandbox link to working demo.
I know this is not the best way. You could directly use the TouchRipple/Ripple component, but I found this way to be very easy to use.
Hope this helps.
I can see this question was not answered, so I'll provide an up-to-date solution (writing this as material-ui is v. 0.18.7 (stable):
You need to import the ripple higher-order comp. (HOC) as:
import TouchRipple from '#material-ui/core/ButtonBase/TouchRipple';
Then you can wrap any component of you choice with TouchRipple, like:
<TouchRipple>
<div>
MY RIPPLING DIV
</div>
</TouchRipple>
Or, if you need a CSS class-based apporach, you can use materialize lib -> https://react-materialize.github.io/#/
In that case, it's as simple as adding a value to waves prop on a material-ui Button, like:
<Button waves='light'>EDIT ME<Icon left>save</Icon></Button>
2021 Update
The most idiomatic way to add the ripple effect when clicking the Card is using the CardActionArea. This component inherits the props of ButtonBase. It also changes the Card background color when hovered and focused (unlike ButtonBase):
<Card>
<CardActionArea>
<CardContent>
{...}
</CardContent>
</CardActionArea>
</Card>
The approach taken in #xiaofan2406 never worked for me, not to mention passing height, width and position seems easily breakable and might not be possible when using flexbox.
However I managed to make it work like:
<YourComponent>
<TouchRipple>
{children}
</TouchRipple>
</YourComponent>
Here is a Solution 2021 updated
simple You need wrap your custom components with component from material ui .
Then add style padding: 0 that solve.
Here I want my Image should react with ripple effect.
You can customize by wrapping with Grid and props container
import { Button } from "#material-ui/core";
function ImageCard(props){
return (
<Button style={{ padding: 0, borderRadius: "16px" }}>
{/*my custom component you can use any component even material ui component also*/}
<img
src={yourImageUrl}
alt="img"
style={{
height: 200,
width: 400,
borderRadius: "16px",//optional
}}
/>
</Button>
);
}
Using component attribute
Instead of wrapping, you can specify the component attribute as the desired component you want it to be. That is, for this use-case;
import ButtonBase from '#material-ui/core/ButtonBase';
...
<Card component = {ButtonBase}>
<CardContent>
...
</CardContent>
</Card>
If you have issues with height or width of the card, add the sx attribute;
<Card component={ButtonBase} sx={{height:'100%', width:'100%'}}>
...
</Card>
If ButtonBase messes up all other buttons on the page, it's better to use just the Button;
import Button from '#mui/material/Button';
...
<Card component = {Button}>
<CardContent>
...
</CardContent>
</Card>
Using MUI V5 (2022)
You can get the benefit of the component prop, use the <ButtonBase> component to get the ripple effect.
Create a React HOC or simply copy this code into a new file:
import React, { forwardRef } from 'react'
import { ButtonBase } from '#mui/material'
export default function WithTouchRipple(OriginalComponent) {
return (props) => {
const Wrapper = !props.component
? ButtonBase
: forwardRef((ButtonBaseProps, ref) => <ButtonBase component={props.component} {...ButtonBaseProps} ref={ref} />)
return <OriginalComponent {...props} component={Wrapper} />
}
}
Then use it as follows on any component you like:
import { Chip, Card, Stack } from '#mui/material'
import WithTouchRipple from '../WithTouchRipple'
const RippleChip = WithTouchRipple(Chip)
const RippleCard = WithTouchRipple(Card)
const RippleStack = WithTouchRipple(Stack)
<RippleChip component={Link} to={`/users/${id}`} {...chipProps} />
<RippleStack>...</RippleStack>
<RippleCard>...</RippleCard>
If you want the ripple effect to appear on the <Card> component, there is a built-in component for that called <CardActionArea>, and you can use it as follows:
<Card>
<CardActionArea>
<CardContent>
{...}
</CardContent>
</CardActionArea>
</Card>
The official api doesn't seem to support it.
But this is what I do, when I want to use material-ui ripple affect:
Use material-ui/internal/TouchRipple, have a look at its source code
Usage example:
<YourComponent>
<TouchRipple style={style}/>
{children}
</YourComponent>
You need to pass the inline style to specify its height, width and position that matches YourComponent's height, width and postion