I am working with React and I need put this button like that:
but I have a big problem because I am forbidden to use margin or other form of positional where I have values with px, or rem, basicaly static positional. Now, I have this code
<div style={{ float: 'right' }}>
<ActionButton style={{
display : 'flex',
flex : '1',
flexDirection: 'row',
alignItems : 'center',
justifyContent : 'center',
height: '40px',
width: '151px',
}} name={<div style = {{
display : 'flex',
flex : '2',
backgroundColor : 'red',
float : 'right'
}}>FILTRAR</div>}
icon={<div style = {{
display : 'flex',
flex : '2',
backgroundColor : 'blue',
width: '24px',
height: '24px',
float : 'left'}}><FilterIcon/></div>}>
</ActionButton>
</div>
And now my button is like that
Parent's styles should already align children (name and icon) by the center, not by the top. And yes, no positioning styles are required, unless there are hardcoded heigh/margin values in children itself.
Desired behavior can be broken because of the implementation of ActionButton.
Anyway, my suggestions to tackle this issue:
use flex-direction: 'row-reverse' instead of floats;
remove display: 'flex' from child elements.
Here is a simplified and working example for web https://codesandbox.io/s/62nynm1wzk, hope it can help you to get started.
Update: here is an example using button instead of div as container, since it is closer to original markup: https://codesandbox.io/s/y7q1vlwkwj
You can use margin in % (ie: 50%) and then use transforms, in percent (ie: transform: translateX(-50%), to adjust position. If you can provide a static stylable html I can produce an example for you.
Try to remove the flex and display style property in name and icon props like below and check it. Because flex:2 will change the width of child element with equal spacing.
<div style={{ float: 'right' }}>
<ActionButton style={{
display : 'flex',
flex : '1',
flexDirection: 'row',
alignItems : 'center',
justifyContent : 'center',
height: '40px',
width: '151px',
}} name={<div style = {{
backgroundColor : 'red',
float : 'right'
}}>FILTRAR</div>}
icon={<div style = {{
backgroundColor : 'blue',
width: '24px',
height: '24px',
float : 'left'}}><FilterIcon/></div>}>
</ActionButton>
</div>
Related
const Btn = () => {
const options = ['test1', 'test2', 'test3'];
return (
<div style={{ position: 'absolute', left: '8px', widht: 'auto', flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', backgroundColor: '#006C84' }}>
{options.map(opt => (
<span style={{ paddingRight: '10px' }}>{opt}</span>)
)}
</div>
)
}
Above is my code and after the end of the text, there is some extra space are left. How to remove that space.
So you are giving paddingRight: 10px to the span, so at the end of the last child it's showing some space left.
There are two ways you can achive this
JS way
Css way
JS way
{options.map((opt,index) => (
<span style={{ paddingRight: options.length - 1 === index ? '10px' : "0px" }}>{opt}</span>)
)}
Css way
you need to change the inline style to explicit style for this, I would say this is the recommended way of giving css over inline style or may be you can create one style object for that.
<div className="parent">
{options.map(opt => (
<span style={{ paddingRight: '10px' }}>{opt}</span>)
)}
</div>
.parent{//parent css goes here}
.parent span:not(::last-of-type){padding-right: 10px}
const Btn = () => {
const options = ['test1', 'test2', 'test3'];
return (
<div style={{ position: 'absolute', left: '8px', widht: 'auto', flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', backgroundColor: '#006C84', display: 'flex', gap: '10px' }}>
{options.map(opt => (
<span>{opt}</span>)
)}
</div>
)
}
use display: flex and gap inside the parent div style
https://codesandbox.io/s/keen-ganguly-kl4ys7?file=/src/App.js
I am working on a react project, where I want to conditionally render a div above an existing div that currently covers the screen with an image. I would like the existing div to reduce in height, by shrinking the size of the image, when the second div conditionally renders. The second div can have a varied height. ( e.g. list of items).
This is simplified version of what I have in my App so far:
function App() {
const [show, setShow] = useState(false);
return (
<div
style={{
border: "solid",
width: "100%",
maxHeight: "100vh"
}}
>
{show && (
<div>
<div style={{ height: "300px", backgroundColor: "red" }}></div>
<button
onClick={() => {
setShow(false);
}}
>
Close
</button>
</div>
)}
<div
style={{
display: "flex",
justifyContent: "center"
}}
>
<img
src="https://i.imgur.com/LiAUjYw.png"
alt="test"
style={{
maxWidth: "100%",
height: "auto"
}}
/>
</div>
<button onClick={() => setShow(true)}>SHow</button>
</div>
);
}
It initially looks like this: https://imgur.com/a/R0e74Xk
And on clicking the 'Show' button, it looks like this: https://imgur.com/a/Iy6osio
As you can see the bottom div gets shifted down, and goes over the container div.
I was wondering how I can make the div responsive enough to change its height when the other element is rendered.
I am fairly new to styling so any help on this would be greatly appreciated.
Thank you.
Here's one simple idea. See how the style is given to the divs like so:
<div
style={{
display: "flex",
justifyContent: "center"
}}
>
Note how the style has this weird {{ }} notation. That's because style accepts an object, and the object here is:
{
display: "flex",
justifyContent: "center"
}
You could take that object and save it as a variable somewhere, for example:
const styleWhenShow = {
display: "flex",
justifyContent: "center",
height: "100px"
}
const styleWhenNoShow = {
display: "flex",
justifyContent: "center",
height: "500px"
}
Since you already have your show state, now it's just a matter of replacing the style prop with:
style={show ? styleWhenShow : styleWhenNoShow}
In case you don't want to repeat some common styles between the show and noshow styles, you can also do something like:
const commonStyle = {
display: "flex",
justifyContent: "center"
}
const styleWhenShow = {
height: "100px"
}
const styleWhenNoShow = {
height: "500px"
}
And set the style prop like:
style={show ? { ...commonStyle, ...styleWhenShow } : { ...commonStyle, ...styleWhenNoShow }}
I want to use the fontAwesome + icon such that it is in the middle of a circle. I want to use it as one icon item. I read that we can use it along with the circle icon and place it inside that but I couldn't make it work.
import IconFA from 'react-native-vector-icons/FontAwesome';
<IconFA
name="plus"
size={moderateScale(30)}
color="black"
style={styles.thumbnail}
/>
{/* <IconFA
name="circle-thin"
size={moderateScale(67)}
color="white"
/> */}
thumbnail: {
height: 68,
width: 68,
position: 'relative',
},
Alternatively, I read about 'stacked' font awesome icons but couldn't understand how to use it in react native.
Reference: https://jsfiddle.net/1d7fvLy5/1/
Snack Expo:
https://snack.expo.io/9Ild0Q1zG
I want to make something like this:
I am also open to using a <Thumbnail> if I find a similar icon's link but I couldn't find any such free icon online.
The JSFiddle example that you posted creates the circle using a CSS border with border-radius to make it circular. We can do pretty much the same thing in react-native, though borderRadius in react-native can only be a fixed number and not a percent (edit: this limitation is specific to typescript since the borderRadius property has type number. Percentage strings do work at runtime).
You can tweak this code however you want, but this will get the job done. You can use IconFA and CircleBorder as two separate nested components but I also made a component IconInCircle which combines the two.
const IconInCircle = ({ circleSize, borderWidth = 2, borderColor = 'black', ...props}) => (
<CircleBorder
size={circleSize}
borderWidth={borderWidth}
borderColor={borderColor}
>
<IconFA {...props} />
</CircleBorder>
);
const CircleBorder = ({ size, borderWidth, borderColor, children }) => (
<View
style={{
width: size,
height: size,
borderRadius: 0.5 * size,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
borderColor,
borderWidth,
}}>
{children}
</View>
);
The IconInCircle component takes three props specific to the border: circleSize, borderWidth, and borderColor. All other props are passed through into the IconFA child component.
Basically what we are doing is placing the icon inside of a fixed-size View with a circular border and centered contents.
Now we can use it like so:
<IconInCircle
name="plus"
size={30}
color="black"
style={styles.thumbnail}
borderWidth={1}
circleSize={50}
/>
Expo Link
Try this, just adjust according to your needs, and also don't forget to support other browsers for flex.
const styles = StyleSheet.create({
thumbnail: {
height: 68,
width: 68,
position: 'relative',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
border: '1px solid #333',
borderRadius: '50%'
},
});
import IconFA from 'react-native-vector-icons/FontAwesome';
<View style={{
position:'relative',
justifyContent:'center',
alignItems:'center',
width:40,
height:40,
backgroundColor:'black'
}}>
<IconFA name='circle-thin' size={40} color='grey'/>
<IconFA name='plus' size={20} color='white' style={{position: 'absolute', zIndex: 99}} />
</View>
I am new to ReactNative, but above snippet should work in your case
Snack Expo
Is there any way to style elements (from the ratings view) in such a way that there's automatically some space between them? I thought of printing text (white spaces) but that doesn't sound like an ideal solution. What else can I do?
<View style={styles.introContainer}>
<Text style={styles.name}>{firstName}</Text>
<View style={styles.ratings}>
<Icon name="user" size={moderateScale(20)} />
<Icon name="star" size={moderateScale(13)} />
<Text style={styles.rating}> {rating}</Text>
</View>
</View>
ratings: {
flexDirection: 'row',
//alignContent: 'center',
alignItems: 'baseline',
},
introContainer: {
alignItems: 'center',
paddingTop: 50,
width: '100%',
},
add margin or padding to whatever element you want to give it more space
or you could apply a width to a few elements and use
display: flex;
justify-content: space-between;
so they are spaced equally
If you are referring to the children of View component you can try to use:
.ratings > * {
// your css here
}
By using > you are targeting direct children of the parent selector ( in this case the .ratings class selector.
* means any kind of children element, although you should be more specific if you can (all children should be targeted by the same class or be the same html element)
css child combinator
UPDATE
Sorry, there is no support for grid by default in React Native, so option 3 is discarded unless you want to use a third-party library like https://www.npmjs.com/package/react-native-responsive-grid
Option 1:
Give the star icon a right and left margin
Option 2:
Add width and display: flex to the ratings style and set the justifyContent to space-between or space-around
Option 3:
Use grid instead of flex and set a grid-gap
I am trying to alter the height of a popover that appears from a select validator form in Material UI. I have tried adding the below CSS to the overall class (and a great many other approaches):
'& .MuiPopover-paper': {
height: '330px',
},
However, neither this nor anything else I've tried seems to be working. I can alter the height property of the element .MuiPopover-paper if I inspect it in the browser console. Plus, changing it there works exactly as expected and gives me the desired result. I know I somehow am not accessing the element properly in the style sheet/code, but none of the approaches I have tried works.
This is the JS/JSX code:
<SelectValidator
id="color"
inputRef={this.formRefs.color}
value={color}
onChange={handleChangeByEvent}
variant="outlined"
name='color'
className={classes.boder}
validators={['required']}
errorMessages={["Please select your vehicle's color"]}
>
<MenuItem value="" className={classes.option}>
<em>None</em>
</MenuItem>
{
vehicleColors.map(color => {
return <MenuItem key={color.id} value={color} className={classes.option}>
{color.name}</MenuItem>
})
}
</SelectValidator>
Here is the corresponding CSS:
border: {
width: '100%',
margin: '7px 0',
borderRadius: '1px',
color: '#333',
fontSize: '14px',
'& .MuiSelect-iconOutlined': {
top: 'auto',
fontSize: '24px',
color: '#fff',
marginRight: '10px',
backgroundImage: `url(${downImg})`,
},
'& .MuiSelect-select': {
height: '48px',
width: '100%',
display: 'flex',
alignItems: 'center',
border: 'solid 1px #6e6e6e',
padding: '0 14px',
backgroundColor: '#ffffff',
fontFamily: 'FordAntenna-Regular',
color: '#333',
fontSize: '14px',
borderRadius: '3px',
},
},
Figured this out after some tinkering. The popover is not a child of the root element or any children of the root. It is created and rendered when the popover is accessed at runtime, using built-in Material-ui classes.
Therefore, the settings for the built-in classes must be overriden.
This can be accomplished by creating a styleOverrides.css file with the code below (must be a .css, adding this code in your styles.js will not work). Then import the .css in the component where the popover you want to alter is generated.
.MuiMenu-paper.MuiPopover-paper {
max-height: 300px //or whatever attribute you want to alter
}