Having a React app with this structure:
index.js
...
ReactDOM.render(
<Provider
store=...
>
<BrowserRouter>
<App>
//other components
</App>
</BrowserRouter>
</Provider>,
document.getElementById('root')
);
App.js
export default (props) => {
return (
<div style={{ backgroundColor: 'red' }}>
<div
className='container'
style={{
width: '100vw',
height: '100vh',
paddingBottom: '32px',
paddingLeft: '37px',
paddingRight: '37px',
paddingTop: '20px',
backgroundColor: 'green',
}}
>
{props.children}
</div>
</div>
);
};
container class contains:
.container {
height: 100vh;
width: 1100vw;
}
My question is: why isn't the green as big as the red one? (plus/minus padding, doesn't matter)
I tried width: 100%, 100wh, auto, etc. No one worked. I want that element to be as big as its parent.
This is how it looks: https://imgur.com/a/maFt9CV
I put a black rectangle over the app's data because it's not important in this case.
The property you are looking for is vw not wh. So changing width: '100wh' to width: '100vw' should solve your problem.
Your container class is adding a
max-width: 960px
to your green rectangle
You can either remove the container class or add
maxWidth: '100vw'
to the styles of your green div
The width units you are using are not right: try with vw or vh instead of wh.
You can check it at MDN - CSS values and units
Note: I have test it, after you fix de units, and the App.js works
Related
I've always been a fan of Google's search bar, with nice rounded corners and ample padding around the text.
I'm trying to replicate this style using Material UI's <Autocomplete/> component, but I can't seem to do it. I'm using Next.js. What I have so far is:
import React, { useState, useEffect } from 'react';
import TextField from '#mui/material/TextField';
import Stack from '#mui/material/Stack';
import Autocomplete from '#mui/material/Autocomplete';
import { borderRadius, Box } from '#mui/system';
import SearchIcon from '#material-ui/icons/Search';
const LiveSearch = (props) => {
const [jsonResults, setJsonResults] = useState([]);
useEffect(() => {
fetch(`https://jsonplaceholder.typicode.com/users`)
.then(res => res.json())
.then(json => setJsonResults(json));
}, []);
return (
<Stack sx={{ width: 400, margin: "auto"}}>
<Autocomplete
id="Hello"
getOptionLabel={(jsonResults) => jsonResults.name}
options={jsonResults}
noOptionsText="No results"
isOptionEqualToValue={(option, value) => {
option.name === value.name
}}
renderOption={(props, jsonResults) => (
<Box component="li" {...props} key={jsonResults.id}>
{jsonResults.name} - Ahhh
</Box>
)}
renderInput={(params) => <TextField {...params} label="Search users..." />}
/>
</Stack>
)
}
export default LiveSearch;
The above code should run as-is – there's an axios call in there to populate the autocomplete results too.
I've tried various way to get the <SearchIcon /> icon prefix inside the input with no success, but really I'd just be happy if I could figure out how to pad it. You can see in the google screenshot how the autocomplete lines up really well with the box, but in my version, the border-radius just rounds the element, and so it no longer lines up with the dropdown.
I'm new to Material UI, so I'm still not quite sure how to do these styles, but I think the issue is that the border is being drawn by some internal element, and although I can set the borderRadius on the component itself global CSS:
.MuiOutlinedInput-root {
border-radius: 30px;
}
I can't seem to set the padding or borders anywhere. I've also tried setting style with sx but it does nothing.
You have to look at the autocomplete css classes and override them in your component or use them in your theme, if you use one.
<Autocomplete
componentsProps={{
paper: {
sx: {
width: 350,
margin: "auto"
}
}
}}
id="Hello"
notched
getOptionLabel={(jsonResults) => jsonResults.name}
options={jsonResults}
noOptionsText="No results"
isOptionEqualToValue={(option, value) => {
option.name === value.name;
}}
renderOption={(props, jsonResults) => (
<Box component="li" {...props} key={jsonResults.id}>
{jsonResults.name} - Ahhh
</Box>
)}
renderInput={(params) => (
<TextField
{...params}
label="Search users..."
sx={{
"& .MuiOutlinedInput-root": {
borderRadius: "50px",
legend: {
marginLeft: "30px"
}
},
"& .MuiAutocomplete-inputRoot": {
paddingLeft: "20px !important",
borderRadius: "50px"
},
"& .MuiInputLabel-outlined": {
paddingLeft: "20px"
},
"& .MuiInputLabel-shrink": {
marginLeft: "20px",
paddingLeft: "10px",
paddingRight: 0,
background: "white"
}
}}
/>
)}
/>
Sandbox: https://codesandbox.io/s/infallible-field-qsstrs?file=/src/Search.js
I'm trying to figure out how to line up the edges (figured it out, see update), but this is how I was able to insert the Search icon, via renderInput and I got rid of the expand and collapse arrows at the end of the bar by setting freeSolo={true} (but this allows user input to not be bound to provided options).
import { Search } from '#mui/icons-material';
import { Autocomplete, AutocompleteRenderInputParams, InputAdornment } from '#mui/material';
...
<Autocomplete
freeSolo={true}
renderInput={(renderInputParams: AutocompleteRenderInputParams) => (
<div ref={renderInputParams.InputProps.ref}
style={{
alignItems: 'center',
width: '100%',
display: 'flex',
flexDirection: 'row'
}}>
<TextField style={{ flex: 1 }} InputProps={{
...renderInputParams.InputProps, startAdornment: (<InputAdornment position='start'> <Search /> </InputAdornment>),
}}
placeholder='Search'
inputProps={{
...renderInputParams.inputProps
}}
InputLabelProps={{ style: { display: 'none' } }}
/>
</div >
)}
...
/>
Ignore the colors and other styling, but this is what it looks like:
Update
I was able to line up the edges by controlling the border-radius via css and setting the bottom left and right to 0 and top ones to 20px.
Here's a demo:
Here are the changes I had to make in css. I also left the bottom border so there is a division between the search and the results, but you can style if however you like. (Also I'm using scss so I declared colors as variables at the top).
div.MuiAutocomplete-root div.MuiOutlinedInput-root { /* Search bar when not in focus */
border-radius: 40px;
background-color: $dark-color;
}
div.MuiAutocomplete-root div.MuiOutlinedInput-root.Mui-focused { /* Search bar when focused */
border-radius: 20px 20px 0px 0px !important;
}
div.MuiAutocomplete-root div.Mui-focused fieldset { /* fieldset element is what controls the border color. Leaving only the bottom border when dropdown is visible */
border-width: 1px !important;
border-color: transparent transparent $light-gray-color transparent !important;
}
.MuiAutocomplete-listbox { /* To control the background color of the listbox, which is the dropdown */
background-color: $dark-color;
}
div.MuiAutocomplete-popper div { /* To get rid of the rounding applied by Mui-paper on the dropdown */
border-top-right-radius: 0px;
border-top-left-radius: 0px;
}
You simply add border radius to fieldset:
<Autocomplete
sx={{ '& fieldset': { borderRadius: 33 }}}
/>
Codesandbox
This is what I have so far:
homepageImage: {
position: "relative",
textAlign: "center",
height: "100vh",
backgroundImage: `linear-gradient(
#3A8DFF,
#86B9FF
), url("images/bg-img.png")`,
},
<div className={classes.homepageImage}>
I got the above code by referencing this Stackoverflow post, but I guess this method doesn't work with JSX? The colors with the gradient displays in the div, but the image does not appear. I can confirm the url is the correct path as I tested with an <img> tag with "images/bg-img.png" as the src and the image appears.
Would it be a better approach to create a gradient with the <img> tag instead of the <div> tag? Not sure where to go from here.
Try this :
You need to use rgba() to specify the opacity of the color.
App.js
import React from 'react';
import './style.css';
export default function App() {
return (
<div>
<h1>How to create an image with color gradient in React's JSX</h1>
<div style={homepageImage} />
</div>
);
}
const homepageImage = {
position: 'relative',
textAlign: 'center',
height: '100vh',
backgroundSize: 'cover',
backgroundImage: `linear-gradient(
rgba(58, 141, 255, 0.9),
rgba(134, 185, 255, 0.3)
), url("https://images.unsplash.com/photo-1593642532400-2682810df593?ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=750&q=80")`
};
Demo : Stackblitz
I have a list with an accordion in react-native, made using the List package from react-native-paper. It works but I would like a helping hand to improve the aesthetic aspect.
As you can see in the screenshot below, the number of objects is not aligned with the other elements. Likewise, but this is a bonus, I would have liked the title to be centered, between quantity and price. And there it is a little complicated, I try to add styles but that does not apply.
I tried that in list.item and in list.accordion:
style={{justifyContent: 'space-between', alignItems: 'center'}}
I would like to know if you can give me any leads, advice or your solution.
Thanks for any help
<List.Section title={item.created_at.substring(0, 10)} titleStyle={{fontSize: 16, color: '#013243'}} key={i.toString()}>
<List.Accordion
title={item.quote_number}
style={{width: '98%'}}
left={props => <List.Icon {...props} color={'#F78400'} icon={require('../../../assets/images/logo.png')} />}>
<List.Item titleStyle={{color: '#F78400'}} title={`Total: ${item.amount} €`}/>
{
item.items.map((product, i) => (
<List.Item
title={product.name.substring(0, 30)}
titleStyle={{fontSize: 14}}
description={product.description}
descriptionStyle={{fontSize: 11}}
descriptionNumberOfLines={4}
key={i.toString()}
left={()=>(<Text>{product.quantity}</Text>)}
right={()=>(<Text>{product.cost} €</Text>)}
/>
))
}
</List.Accordion>
</List.Section>
It can be corrected by applying style to the left and right props as follows:
<List.Item
title={product.name.substring(0, 30)}
titleStyle={{fontSize: 14}}
description={product.description}
descriptionStyle={{fontSize: 11}}
descriptionNumberOfLines={4}
key={i.toString()}
left={()=>(<Text style = {styles.textStyle}>{product.quantity}</Text>)} // styled
right={()=>(<Text style = {styles.textStyle}>{product.cost} €</Text>)} // styled
/>
const styles = Stylesheet.create({
textStyle: {
marginTop: 4, // you may adjust this value according to your requirement
fontSize: 14,
}
})
You can do it easily adding the proper style in every item. Check the bellow snippet. In this way you align vertically the number of objects and also the title is centered.
.product {
width: 500px;
height: 100px;
background-color: black;
color: white;
padding: 5px 10px;
display: flex;
justify-content: space-between;
align-items: center
}
<div class="product">
<div>1</div>
<div>Product 1 title</div>
<div>234.54$</div>
</div>
I have a problem with a Material-UI Table component and its size and scrollability.
Short:
The Material-UI table component becomes only scrollable, if its parent has a fixed size. If I set the size to fit the parent 100%, it overflows.
Long:
I have a simple WebApp in Reactjs that consists of a header, a body (where the table lives) and a footer. My App component is styled to distribute those three base layout components as follows:
const useStyles = makeStyles((theme) => ({
root: {
height: "100vh",
maxHeight: "100vh",
display: "grid",
gridTemplateRows: "auto 1fr auto",
},
}));
That works just fine. My body component takes up all the available space to fill the full viewport. The component looks as follows:
<div className={classes.root}>
<Controls /> //just some buttons, arranged in one line
<Table /> //my table component, which uses pagination
</div>
The table itself uses pagination and mounts with a default of 10 rows per page.
And the CSS for it looks like that:
root: {
maxHeight: "100%",
display: "grid",
gridTemplateRows: "min-content 1fr",
gap: "25px",
},
The table component itself looks like this:
<div className={classes.root}>
{loading ? loadingAlert : <></>}
<Paper elevation={3} className={classes.tableRoot}>
<TableContainer className={classes.container}>
<Table size="small" stickyHeader aria-label="sticky table">
[...]
The CSS for my Table component looks like that:
const useStyles = makeStyles({
root: {
maxHeight: "100%",
},
tableRoot: {
width: "100%",
maxHeight: "100%",
},
container: {
maxHeight: "100%", <---
},
footer: {
display: "grid",
gridTemplateColumns: "1fr min-content",
},
});
When the user changes the displayed rows per page from 10 to 25, the height of the table changes. In that case, I want the table to take up all the free space within body and become scrollable. If I set the maxHeight of container to a fixed pixel-value, the table becomes scrollable and won't overflow. If I leave it like that, the table overflows and user has to scroll to reach the end of the page.
Can anyone tell me how I can set the height for my container to fit its parent 100% without my table overflowing?
if you use a DataGrid of Material UI, you can use a prop called autoHeight
<DataGrid autoHeight {...data} />
<p>more content</p>
you can check more details in this docs
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