react how can fit div width like android wrap-content? - html

const SearchBar = (text, onChange) => {
return (
<div>
<div style={{flexWrap: "wrap", background: 'red', border: "1px solid", borderRadius: 10}}>
<Search style={{background: 'blue', verticalAlign: 'bottom'}}/>
<input style={{background: 'blue', verticalAlign: 'bottom'}}
text={text} onChange={onChange}/>
</div>
</div>
);
};
export default SearchBar;
Here is my search bar code.
The result is
but, I want it to appear like this.
How can I get the result?

In your Search component make the width to be 100%.
<Search style={{background: 'blue', verticalAlign: 'bottom', width:'100%'}}/>

First import FaSearch then replace your code with below mentioned.
import { FaSearch } from "react-icons/fa";
const App =(text, onChange)=> {
return (
<>
<div style={styles.mainStyle}>
<Search />
<input style={styles.inputStyle} text={"text"} onChange={null} />
</div>
</>
);
}
const Search = () => <FaSearch style={styles.search} />;
const styles = {
mainStyle: {
display: "flex",
flexWrap: "wrap",
borderRadius: 10,
alignItems: "center",
border: "1px solid",
overflow: "hidden"
},
inputStyle: {
flex: 1,
border: "none",
height: 30
},
search: {
fontSize: 30,
padding: "0px 10px",
cursor: "pointer",
borderRight: '1px solid grey'
}
};

Related

Why does my stretch attribute in mui flexbox not do anything?

So I want the boxes I have displayed in a parent box to completely stretch out. I followed the documentation on MUI for the flexbox, though after editing it a bit I do not understand why it does not work anymore :?
I have given the inner items a minimum for width and height, but even without this the items do not stretch.
Does the stretch attribute not mean that the parent container will be completely filled out?
Here's my code:
import "./styles.css";
import React from "react";
import Box, { BoxProps } from "#mui/material/Box";
import PropTypes from "prop-types";
function Item(props) {
const { sx, ...other } = props;
return (
<Box
sx={{
border: "1px solid pink",
borderRadius: 2,
fontSize: "0.875rem",
minHeight: "5rem",
minWidth: "5rem",
...sx
}}
{...other}
/>
);
}
Item.propTypes = {
sx: PropTypes.oneOfType([
PropTypes.arrayOf(
PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])
),
PropTypes.func,
PropTypes.object
])
};
export default function App() {
const items = [
{
title: "Car",
color: "yellow"
},
{
title: "Plane",
color: "lightblue"
},
{
title: "Bicycle",
color: "lightgreen"
},
{
title: "Train",
color: "orange"
}
];
const movies = [
{
title: "Seven",
color: "red"
},
{
title: "Memento",
color: "white"
},
{
title: "Vivarium",
color: "lightgreen"
},
{
title: "Blue Velvet",
color: "lightblue"
}
];
return (
<>
<Box
className="Container Of Sub"
style={{
backgroundColor: "lightpink",
display: "flex",
alignItems: "center",
width: "100%",
height: "100%"
}}
>
<Box className="FirstSub" style={{ width: "50%" }}>
<Box
className="Header"
style={{
borderRadius: "10px",
paddingLeft: "10px",
boxShadow: "4px 4px 20px 0px rgba(0,0,0,0.25",
backgroundColor: "white"
}}
>
<h4>Subcategory 1</h4>
</Box>
<Box
className="Category Holder"
sx={{
display: "flex",
flexWrap: "wrap",
alignContent: "stretch",
borderRadius: 1
}}
>
{items.map((item) => (
<Item
sx={{
backgroundColor: item.color
}}
>
{item.title}
</Item>
))}
</Box>
</Box>
<Box
className="2ndSubCategory"
style={{
width: "50%",
marginLeft: "20px"
}}
>
<Box
className="Header"
style={{
borderRadius: "10px",
paddingLeft: "10px",
boxShadow: "4px 4px 20px 0px rgba(0,0,0,0.25",
backgroundColor: "white"
}}
>
<h4>Subcategory 2</h4>
</Box>
<Box
className="Category Holder"
sx={{
display: "flex",
flexWrap: "wrap",
alignContent: "stretch",
borderRadius: 1
}}
>
{movies.map((item) => (
<Item
sx={{
backgroundColor: item.color
}}
>
{item.title}
</Item>
))}
</Box>
</Box>
</Box>
</>
);
}

How to mute remote user in Agora UI kit?

I am using AgoraUIKit from "agora-react-uikit". it is supposed to have the option to mute remote users as per their documentation, but it is not there as they showed in their demo example.
Here is the github link for controls panal which is supposed to be there by default.
https://github.com/AgoraIO-Community/VideoUIKit-Web-React/wiki/Guide#controls
Here is a code of the App.tsx file
import React, { CSSProperties, useState } from 'react'
import AgoraUIKit, { layout, VideoPlaceholderProps, BtnTemplate } from 'agora-react-uikit'
import 'agora-react-uikit/dist/index.css'
const PageComponent: React.FunctionComponent<VideoPlaceholderProps> = ({isShown=true, showButtons=true, showSwap=false}) => {
return (
<>
{showButtons}{isShown}{showSwap}
{BtnTemplate}
</>
);
};
const App: React.FunctionComponent = () => {
const [videocall, setVideocall] = useState(false)
const [isHost, setHost] = useState(true)
const [isPinned, setPinned] = useState(false)
const [username, setUsername] = useState('')
return (
<div style={styles.container}>
<div style={styles.videoContainer}>
{videocall ? (
<>
<div style={styles.nav2}>
<h3 style={styles.heading}>Online Video Call</h3>
<p style={styles.btn} onClick={() => setPinned(!isPinned)}>
Change Layout
</p>
</div>
<AgoraUIKit
rtcProps={{
appId: 'appid',
channel: 'channel name',
uid: 0,
token: 'token', // add your token if using app in secured mode
role: isHost ? 'host' : 'audience',
layout: isPinned ? layout.pin : layout.grid,
activeSpeaker: true,
disableRtm: false,
enableScreensharing: true,
CustomVideoPlaceholder: PageComponent,
}}
rtmProps={{
username: username || 'user',
displayUsername: true,
showPopUpBeforeRemoteMute: true
}}
callbacks={{
EndCall: () => setVideocall(false)
}}
styleProps={{
localBtnContainer: { backgroundColor: 'white', justifyContent: 'center', gap: "20px" },
> BtnTemplateStyles: { borderColor: 'rgb(107 107 107)' },
}}
/>
</>
) : (
<div style={styles.nav}>
<input
style={styles.input}
placeholder='nickname'
type='text'
value={username}
onChange={(e) => {
setUsername(e.target.value)
}}
/>
<h3 style={styles.btn} onClick={() => setVideocall(true)}>
Start Call
</h3>
</div>
)}
</div>
</div>
)
}
const styles = {
container: {
maxWidth: '1100px',
margin: "0 auto",
height: '100vh',
display: 'flex',
flex: 1,
},
container2: {
padding: "2px 16px"
},
heading: { textAlign: 'center' as const, marginBottom: 0 },
videoContainer: {
display: 'flex',
flexDirection: 'column',
flex: 1
} as CSSProperties,
nav: { display: 'flex', justifyContent: 'space-between' },
nav2: { display: 'flex', justifyContent: 'space-between', borderBottom: "1px solid black" },
card: {
// position:"absolute",
// left:"0",
// bottom:"0",
// transform:"translate(155px, -82px)",
// boxShadow: '0 4px 8px 0 rgba(0,0,0,0.2)',
// transition: '0.3s',
// display: 'flex',
// width:"80vw",
// height:"80vh",
// flexDirection: "column",
// justifyContent: "space-between"
} as CSSProperties,
btn: {
backgroundColor: '#007bff',
cursor: 'pointer',
borderRadius: 5,
padding: '4px 8px',
color: '#ffffff',
fontSize: 20
},
input: { display: 'flex', height: 24, alignSelf: 'center' } as CSSProperties
}
export default Apptype here

Button is moved out of the visible content

I've got a problem with my CSS styling. I've got some example headers with the possibility to add some header bookmarks with help of the "PLUS" button. You can see the code here: https://codesandbox.io/s/condescending-feather-wjxfuu?file=/src/App.js or:
import React, { useState } from "react";
export default function App() {
const [list, setList] = useState([]);
const handleAddItem = () => {
const newItem = { id: list.length, name: `Item ${list.length + 1}` };
setList([...list, newItem]);
};
const handleRemoveItem = (index) => {
setList(list.filter((item) => index !== item.id));
};
return (
<div className="App">
<div
style={{
width: "400px",
height: "50px",
display: "flex",
alignItems: "center",
gap: "8px",
overflow: "hidden",
padding: "8px",
border: "1px solid red"
}}
>
{list.map((item, i) => (
<div
key={i}
style={{
border: "1px solid blue",
borderRadius: "5px",
padding: "4px",
backgroundColor: "blue",
color: "white",
cursor: "pointer",
overflow: " hidden",
whiteSpace: "nowrap",
textOverflow: "ellipsis"
}}
onClick={() => handleRemoveItem(i)}
>
{item.name}
</div>
))}
<button onClick={handleAddItem}>+</button>
</div>
</div>
);
}
The problem is, that when I add some number of the bookmarks, then in some cases the "PLUS" button starts to overflow the div container(header) as you can see in the GIF.
I want the button not to overflow the content.
You can add another div to keep all your items separate from your button
You can try this playground
import React, { useState } from "react";
export default function App() {
const [list, setList] = useState([]);
const handleAddItem = () => {
const newItem = { id: list.length, name: `Item ${list.length + 1}` };
setList([...list, newItem]);
};
const handleRemoveItem = (index) => {
setList(list.filter((item) => index !== item.id));
};
return (
<div className="App">
<div
style={{
width: "400px",
height: "50px",
display: "flex",
alignItems: "center",
gap: "8px",
overflow: "hidden",
padding: "8px",
border: "1px solid red"
}}
>
<div
style={{
height: "50px",
display: "flex",
alignItems: "center",
gap: "8px",
overflow: "hidden"
}}
>
{list.map((item, i) => (
<div
key={i}
style={{
border: "1px solid blue",
borderRadius: "5px",
padding: "4px",
backgroundColor: "blue",
color: "white",
cursor: "pointer",
overflow: " hidden",
whiteSpace: "nowrap",
textOverflow: "ellipsis"
}}
onClick={() => handleRemoveItem(i)}
>
{item.name}
</div>
))}
</div>
<button onClick={handleAddItem}>+</button>
</div>
</div>
);
}
Hi, Simply make the button directly in the div classed app <div className="App">
import React, { useState } from "react";
export default function App() {
const [list, setList] = useState([]);
const handleAddItem = () => {
const newItem = { id: list.length, name: `Item ${list.length + 1}` };
setList([...list, newItem]);
};
const handleRemoveItem = (index) => {
setList(list.filter((item) => index !== item.id));
};
return (
<div className="App">
<div
style={{
width: "400px",
height: "50px",
display: "flex",
alignItems: "center",
gap: "8px",
overflow: "hidden",
padding: "8px",
border: "1px solid red"
}}
>
{list.map((item, i) => (
<div
key={i}
style={{
border: "1px solid blue",
borderRadius: "5px",
padding: "4px",
backgroundColor: "blue",
color: "white",
cursor: "pointer",
overflow: " hidden",
whiteSpace: "nowrap",
textOverflow: "ellipsis"
}}
onClick={() => handleRemoveItem(i)}
>
{item.name}
</div>
))}
</div>
<button onClick={handleAddItem}>+</button>
</div>
);
}

Material-UI NextJS Button Styling Issue

i am having a problem getting the styling right on a couple of buttons in JS, it seems when i add a styling class via className that on first render the formatting works, but on subsequent refreshes it loses its styling. It is only happening on the two individual buttons i have. After troubleshooting for ages, i have found that everything works when i use SX instead of classNames, so if i do this then the refresh works. So in code below one button styles and remains styles, but the second one, refreshing my button class does not? Stumped at this point, i ran through forums and see a lot about NextJs needing some extra config in _document and _app to make it work, but i ran this in from the NextJs Material UI boiler plate from Git so dont think it could be that causing it.
Code:
import React from 'react'
import { AppBar, Toolbar, alpha } from "#mui/material";
import Button from '#mui/material/Button'
import ButtonBase from '#mui/material/ButtonBase';
import { styled } from '#mui/material/styles';
import Typography from '#mui/material/Typography';
import InputBase from '#mui/material/InputBase';
import SearchIcon from '#mui/icons-material/Search';
import AddIcon from '#mui/icons-material/Add';
import { makeStyles } from '#mui/styles'
const useStyles = makeStyles(theme => ({
button: {
...theme.typography.mainmenu,
borderRadius: "40px",
width: "230px",
height: "130px",
marginLeft: "30px",
alignItem: "center",
"&:hover": {
backgroundColor: theme.palette.secondary
},
[theme.breakpoints.down("sm")]: {
width: '100% !important', // Overrides inline-style
height: 100
},
},
}))
/*Image Button Styling Begins*/
const images = [
{
url: '/assets/breakfastMenu.jpg',
title: 'Breakfast',
width: '20%',
},
{
url: '/assets/steak.jpg',
title: 'Mains',
width: '20%',
},
{
url: '/assets/desserts.jpg',
title: 'Desserts',
width: '20%',
},
];
const Image = styled('span')(({ theme }) => ({
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
color: theme.palette.common.primary,
}));
const ImageButton = styled(ButtonBase)(({ theme }) => ({
position: 'relative',
height: 150,
[theme.breakpoints.down('sm')]: {
width: '100% !important', // Overrides inline-style
height: 100,
},
'&:hover, &.Mui-focusVisible': {
zIndex: 1,
'& .MuiImageBackdrop-root': {
opacity: 0.15,
},
'& .MuiImageMarked-root': {
opacity: 0,
},
'& .MuiTypography-root': {
border: '4px solid currentColor',
},
},
}));
const ImageSrc = styled('span')({
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
backgroundSize: 'cover',
backgroundPosition: 'center 40%',
});
const ImageBackdrop = styled('span')(({ theme }) => ({
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
backgroundColor: theme.palette.common.black,
opacity: 0.4,
transition: theme.transitions.create('opacity'),
}));
const ImageMarked = styled('span')(({ theme }) => ({
height: 3,
width: 18,
backgroundColor: theme.palette.common.white,
position: 'absolute',
bottom: -2,
left: 'calc(50% - 9px)',
transition: theme.transitions.create('opacity'),
}));
/*Image Button Styling Ends*/
const Search = styled('div')(({ theme }) => ({
position: 'relative',
borderRadius: theme.shape.borderRadius,
backgroundColor: alpha(theme.palette.common.white, 0.15),
'&:hover': {
backgroundColor: alpha(theme.palette.common.white, 0.25),
},
marginLeft: 0,
width: '100%',
[theme.breakpoints.up('sm')]: {
marginLeft: theme.spacing(1),
width: 'auto',
},
}));
const SearchIconWrapper = styled('div')(({ theme }) => ({
padding: theme.spacing(0, 2),
height: '100%',
position: 'absolute',
pointerEvents: 'none',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}));
const StyledInputBase = styled(InputBase)(({ theme }) => ({
color: 'inherit',
'& .MuiInputBase-input': {
padding: theme.spacing(1, 1, 1, 0),
// vertical padding + font size from searchIcon
paddingLeft: `calc(1em + ${theme.spacing(4)})`,
transition: theme.transitions.create('width'),
width: '100%',
[theme.breakpoints.up('sm')]: {
width: '12ch',
'&:focus': {
width: '20ch',
},
},
},
}));
const Header = () => {
const classes = useStyles();
return (<React.Fragment>
<AppBar position="sticky" className={classes.appBar}>
<Toolbar disableGutters>
{images.map((image) => (
<ImageButton
focusRipple
key={image.title}
style={{
width: image.width,
}}
>
<ImageSrc style={{
backgroundImage: `url(${image.url})`
}} />
<ImageBackdrop className="MuiImageBackdrop-root" />
<Image>
<Typography
component="span"
variant="subtitle1"
color="white"
fontWeight="bold"
sx={{
position: 'relative',
p: "7em",
pt: "2em",
pb: (theme) => `calc(${theme.spacing(1)} + 6px)`,
}}
>
{image.title}
<ImageMarked className="MuiImageMarked-root" />
</Typography>
</Image>
</ImageButton>
))}
<Button size="large" variant="contained" color="secondary"
startIcon={<AddIcon />}
sx={{
borderRadius: "40px", borderRadius: "40px",
width: "230px",
height: "130px",
marginLeft: "30px",
alignItem: "center",
}} >Add A recipe</Button>
<Button size="large" variant="contained" color="secondary" className={classes.button}>Meals for the Week</Button>
<Search>
<SearchIconWrapper>
<SearchIcon />
</SearchIconWrapper>
<StyledInputBase
placeholder="Search…"
inputProps={{ 'aria-label': 'search' }}
/>
</Search>
</Toolbar>
</AppBar>
</React.Fragment >
)
}
export default Header
Exactly, you need to add some configuration to the _document.tsx in order to make the styles work properly with the NextJS server side rendering feature. The reason behind this is that you need that some styles are injected in the DOM for you.
As you can see in the MUI docs, you can use the ServerStyleSheets to handle the server side rendering properly.
This is the code I have in my _document.tsx
import React from 'react';
import Document, { Html, Main, NextScript } from 'next/document';
import { ServerStyleSheets } from '#mui/styles';
export default class MyDocument extends Document {
render() {
return (
<Html>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
MyDocument.getInitialProps = async (ctx) => {
// Render app and page and get the context of the page with collected side effects.
const sheets = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) => sheets.collect(<App {...props} />)
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
// Styles fragment is rendered after the app and page rendering finish.
styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()]
};
};
You can read more information about this in these Server rendering - MUI docs

Inconsistent margins/spacing with Material UI Accordion

I'm using Material UI Accordion for creating a filter menu.
It looks like this on some devices whereas it looks likes this on other devices with different dimensions even though the margins between the items are the same and uses the same code. On resizing the dimensions of the screen, the inconsistency changes.
How to fix this inconsistency with the spacing between each filter item?
Here's my file FilterAccordion.tsx:
<Box className={classes.accordionRoot}>
<Accordion style={{ boxShadow: "none" }} defaultExpanded={true}>
<AccordionSummary
expandIcon={<ExpandMore style={{ fill: "#d3d3d3" }} />}>
<div className={classes.verticalrootcontainer}>
<Icon
onClick={(e) => e.stopPropagation()}
style={{
fill: "#d3d3d3",
width: "2rem",
marginRight: "1rem",
transform: "scale(3)",
zIndex: -1,
}}
/>
<Typography
variant="body1"
className={`titleAquire ${classes.title}`}>
{title}
</Typography>
</div>
</AccordionSummary>
<AccordionDetails>
<div className={classes.listRoot}>
{Object.keys(groupByPacks).map((item, index) => {
let checked = isChecked(item);
return (
<div
key={index}
className={`${classes.list} ${
checked ? classes.selected : ""
}`}
onClick={() => handleOnCheck(item)}>
<Typography variant="body1" className={classes.item}>
{item}
</Typography>
<Typography variant="body1" className={classes.item}>
{groupByFilteredPacks[item]
? groupByFilteredPacks[item]?.length
: 0}
</Typography>
</div>
);
})}
</div>
</AccordionDetails>
</Accordion>
</Box>
And the CSS file:
accordionRoot: {
"& .MuiAccordion-root": {
background: "transparent",
},
"& .MuiAccordionDetails-root": {
padding: "0px",
},
"& .MuiAccordionSummary-root": {
padding: "0px",
marginBottom: "-1rem",
},
"& .MuiCollapse-entered": {
marginTop: "1rem",
},
},
title: {
fontSize: "18px",
color: theme.on.dark,
},
verticalrootcontainer: {
display: "flex",
alignItems: "center",
},
list: {
display: "flex",
width: "100%",
alignItems: "center",
justifyContent: "space-between",
marginTop: "0.2rem",
padding: "0.2rem 0.5rem",
cursor: "pointer",
"&:first-child": {
marginTop: 0,
},
},
item: {
textTransform: "uppercase",
color: theme.on.dark,
opacity: "30%",
},
selected: {
background: theme.on.dark,
"& p": {
color: theme.darkMode.light,
opacity: "100%",
},
},
listRoot: {
width: "100%",
},