I am trying to implement a select dropdown option with image by the left side of the text. I used react-select library but the image shows broken.
Here is my code:
import React from 'react'
import Select from 'react-select'
import { components } from 'react-select';
import { login } from "../customSelect/login.png";
const options = [
{
label: 'Option 1',
value: 0,
image: "../customSelect/login.png",
},
{
label: 'Option 2',
value: 1,
image: "../customSelect/login.png",
}
];
const customStyles = {
option: (provided) => ({
...provided,
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
}),
singleValue: (provided) => ({
...provided,
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
}),
}
const { SingleValue, Option } = components;
const IconSingleValue = (props) => (
<SingleValue {...props}>
<img src={props.data.image}
style={{ height: '30px', width:
'30px', borderRadius: '50%', marginRight: '10px' }}/>
{props.data.label}
</SingleValue>
);
const IconOption = (props) => (
<Option {...props}>
<img src={props.data.image}
style={{ height: '30px', width: '30px', borderRadius: '50%',
marginRight: '10px' }}/>
{props.data.label}
</Option>
);
const SelectOption = () => {
return (
<div>
<Select
styles={customStyles}
components={{SingleValue:IconSingleValue,
Option:IconOption}}
options={options}
/>
</div>
)
}
export default SelectOption
this is the result i got
Related
How can I add a description or sub paragraph to my Menu item using antd library?
Help would be most grateful. Thank you.
Here is an example picture:
Menu item paragraph
Here is my code, tried adding the title prop from antd library or even importing description, but it is not displaying:
function MegaMenu() {
const UserIcon = (props) => <Icon component={UserSvg} {...props} />;
const navigate = useNavigate();
const [selectedKeys, setSelectedKeys] = useState([]);
const onMenuItemClick = (item) => {
setSelectedKeys([item.key]);
console.log("Selected Mega Item", item.key);
};
return (
<div
style={{
backgroundColor: "white",
paddingLeft: 20,
paddingRight: 20,
alignItems: "top",
minWidth: "100%",
borderRadius: "0%",
}}
>
<Space
direction="horizontal"
size={9}
style={{ boxShadow: "none", border: "none" }}
>
<Space
direction="horizontal"
style={{ boxShadow: "none", border: "none" }}
>
<Menu
onClick={({ key }) => {
if (key === "MegaMenu") {
} else {
navigate(key);
}
}}
selectedKeys={selectedKeys}
items={[
{
label: "VIR WIE",
key: "vir_wie",
type: "group",
},
{
type: "divider",
},
{
label: "Werknemers",
key: "/werknemers",
icon: <UserIcon/>,
},
]}
style={{
boxShadow: "none",
border: "none",
justifyContent: "top",
alignItems: "top",
}}
/>
in the following code, how do I define itemData as post.images[i]?
import clientPromise from "../lib/mongodb";
import Box from '#mui/material/Box';
import Avatar from '#mui/material/Avatar';
import IconButton from '#mui/material/IconButton';
import ChatBubbleOutlineRoundedIcon from '#mui/icons-material/ChatBubbleOutlineRounded';
import FavoriteBorderRoundedIcon from '#mui/icons-material/FavoriteBorderRounded';
import ShareRoundedIcon from '#mui/icons-material/ShareRounded';
import Button from '#mui/material/Button';
import ImageList from '#mui/material/ImageList';
import ImageListItem from '#mui/material/ImageListItem';
export default function Posts({ posts }) {
return (
<div>
<ul>
<div style={{ width: '100%' }}>
<Box sx={{ display: 'flex', justifyContent: 'center'}}>
<div style={{ width: '75%' }}>
{posts.map((post) => (
<li style={{ border: '1px solid grey', borderRadius: '12px', margin: "10px", padding: "10px" }}>
<Box sx={{ display: 'flex', justifyContent: 'start', alignItems: 'center'}}>
<Avatar alt={post.userName} src={post.userAvatar}/>
<h4 style={{ paddingLeft:'20px', paddingRight: '20px' }}>{post.userName}</h4>
<p style={{ color: 'grey', fontSize: '12px' }}>{post.timestamp}</p>
</Box>
<Box>
<p style={{ display: 'block', width: '100%', margin: '0'}}>{post.text}</p>
</Box>
<Box sx={{ my: 1, display: 'flex', justifyContent: 'end', alignItems: 'center'}}>
<IconButton><ChatBubbleOutlineRoundedIcon/></IconButton>
<IconButton><FavoriteBorderRoundedIcon/></IconButton>
<IconButton><ShareRoundedIcon/></IconButton>
</Box>
<Box><Button href={post.link} variant="outlined">Link</Button></Box>
<Box>
<ImageList sx={{ width: 500, height: 450 }} cols={3} rowHeight={164}>
{itemData.map((item) => (
<ImageListItem key={item.img}>
<img
src={`${item.img}?w=164&h=164&fit=crop&auto=format`}
srcSet={`${item.img}?w=164&h=164&fit=crop&auto=format&dpr=2 2x`}
alt={item.title}
loading="lazy"
/>
</ImageListItem>
))}
</ImageList>
</Box>
</li>
))}
</div>
</Box>
</div>
</ul>
</div>
)
}
const itemData = [
{
img: 'https://images.unsplash.com/photo-1523217582562-09d0def993a6',
title: 'House',
},
{
img: 'https://images.unsplash.com/photo-1615874694520-474822394e73',
title: 'Living Room',
},
{
img: 'https://images.unsplash.com/photo-1616594039964-ae9021a400a0',
title: 'Bedroom',
},
{
img: 'https://images.unsplash.com/photo-1616486886892-ff366aa67ba4',
title: 'Dining Room',
},
{
img: 'https://images.unsplash.com/photo-1521783593447-5702b9bfd267',
title: 'Bathroom',
}
];
export async function getServerSideProps() {
try {
const client = await clientPromise;
const db = client.db("abode-app");
const posts = await db
.collection("posts")
.find({})
.sort({ metacritic: -1 })
.limit(20)
.toArray();
return {
props: { posts: JSON.parse(JSON.stringify(posts)) },
};
} catch (e) {
console.error(e);
}
}
I have tried loading the images one by one and they work, but prefer to loop over them.
I'm trying to migrate my project from Material-UI v4 to MUI v5 using this How to customize guide from the official website but can't wrap my head how can I rewrite this component with the new guidelines:
...
const useStyles = makeStyles(() => ({
root: {
backgroundColor: "rgba(255, 255, 255, 0.36)",
display: "flex",
height: "100%",
position: "absolute",
textAlign: "center",
top: 0,
width: "100%",
justifyContent: "center",
alignItems: "center",
},
visible: {
visibility: "visible",
},
hidden: {
visibility: "hidden",
},
holder: {
height: 60,
width: 60,
},
}));
interface ILoaderBlockProps {
isLoading: boolean;
className?: string;
testId?: string;
}
type Props = ILoaderBlockProps;
const LoaderBlock: FunctionComponent<Props> = (props: Props) => {
const classes = useStyles({});
const { isLoading, className } = props;
const rootClasses = clsx(
classes.root,
isLoading ? classes.visible : classes.hidden,
className
);
return (
<div className={rootClasses}>
<div className={classes.holder}>
<CircularProgress color={"primary"}/>
</div>
</div>
);
};
...
Since makeStyles is deprecated and I have additional difficulties in MUI v5, I'm trying to stop using it but can't wrap my head around new styling yet.
How could these <div>s be rewritten in new, v5-way since makeStyles is no longer an option?
It seems the only way to do it is to introduce SCSS/CSS file with styles for root and holder.
Here's what I came up with (thanks #morganney for suggestion!):
...
const LoaderBlockRoot = styled("div")(() => ({
backgroundColor: "rgba(255, 255, 255, 0.36)",
display: "flex",
height: "100%",
position: "absolute",
textAlign: "center",
top: 0,
width: "100%",
justifyContent: "center",
alignItems: "center",
}));
const Holder = styled("div")(() => ({
height: 64,
width: 64
}));
const LoaderBlock: FunctionComponent<Props> = (props: Props) => {
const { isLoading } = props;
return (
<LoaderBlockRoot sx={{ visibility: isLoading ? "visible" : "hidden" }}>
<Holder>
<CircularProgress color={"primary"} />
</Holder>
</LoaderBlockRoot>
);
};
...
A bit clumsy for my taste compared to withStyles practices though, I wonder if this could be improved.
Also, I still don't know what to do if I want to override style of component (previously, it was doable by passing prop.className into component).
While the preferred way of styling in v5 is through styled or the sx prop, makeStyles still works. (Why do you say it's deprecated; it's in the v5 docs. You can even get rid of clsx by passing in the props directly into useStyles as shown in the docs example.) The code below works fine for me in v5.
As for overriding, it's still doable even with styled or sx prop. Just target the classname by using the component-slot class name convention (docs)
import { FC, useEffect, useState } from 'react'
import clsx from 'clsx'
import { makeStyles } from '#mui/styles'
import { CircularProgress } from '#mui/material'
const useStyles = makeStyles({
root: {
backgroundColor: 'rgba(255, 255, 255, 0.36)',
display: 'flex',
height: '100%',
position: 'absolute',
textAlign: 'center',
top: 0,
width: '100%',
justifyContent: 'center',
alignItems: 'center',
},
visible: {
visibility: 'visible',
},
hidden: {
visibility: 'hidden',
},
holder: {
height: 60,
width: 60,
},
})
export const UseStyles: FC = () => {
const [loading, setLoading] = useState(true)
const classes = useStyles()
useEffect(() => {
setTimeout(() => setLoading(false), 3000)
}, [])
const rootClasses = clsx(
classes.root,
loading ? classes.visible : classes.hidden,
)
return (
<div className={rootClasses}>
<div className={classes.holder}>
<CircularProgress color={'primary'} />
</div>
</div>
)
}
I can't believe that I'm asking an obvious question, but I still get the error in console log.
Console says that it can't find the module in the directory, but I've checked at least 10 times for typos. Anyways, here's the component code.
I want to render MainTemplate in root
import React from 'react';
import MainTemplate from './components/MainTemplate';
const App = () => {
return (
<MainTemplate></MainTemplate>
);
}
export default App;
This is the MainTemplate component
import React from 'react';
import Categories from './components/Categories';
const Maintemplate = () => {
const MainTemplate = {
display: 'flex',
};
const HeaderTemplate = {
backgroundColor: '#0bb286',
color: '#fff',
fontSize: '32px',
padding: '20px',
width: '100%',
};
const CrawlTemplate = {
backgroundColor: '#eeeeee',
width: '750px',
height: '1050px',
margin: '80px',
padding: '40px',
fontSize: '30px',
textAlign: 'center',
justifyContent: 'center',
flexDirection: 'row',
alignItems: 'flex-start',
justifyContent: 'space-between',
flex: '1',
marginTop: '60px',
};
const TutoringTemplate = {
backgroundColor: '#eeeeee',
width: '750px',
height: '1050px',
margin: '80px',
padding: '40px',
fontSize: '30px',
textAlign: 'center',
justifyContent: 'center',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
flex: '1',
marginTop: '60px',
};
const GroupStudyTemplate = {
backgroundColor: '#eeeeee',
width: '750px',
height: '1050px',
margin: '80px',
padding: '40px',
fontSize: '30px',
textAlign: 'center',
justifyContent: 'center',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
flex: '1',
marginTop: '60px',
};
const footerTemplate = {
backgroundColor: '#0bb286',
color: '#fff',
fontSize: '32px',
textAlign : "center",
padding: '20px',
width: '100%',
}
return (
<div>
<div className="HeaderTemplate" style={HeaderTemplate}>
튜터링/학습공동체 및 비교과활동 모음 사이트
</div>
<div className="MainTemplate" style={MainTemplate}>
<div className="CrawlTemplate" style={CrawlTemplate}>
<Categories/>
</div>
<div className="TutoringTemplate" style={TutoringTemplate}>
튜터링 활동신청 part
</div>
<div className="GroupStudyTemplate" style={GroupStudyTemplate}>
학습공동체 활동신청 part
</div>
</div>
<div className="footerTemplate" style={footerTemplate}>
박종준 #copy & right
</div>
</div>
);
};
export default Maintemplate;
This is the Categories component
import React from 'react';
import styled from 'styled-components';
const categories = [
{
name: 'All',
text: '전체'
},
{
name: 'Bachelor',
text: '학사'
},
{
name: 'Scholarship',
text: '장학'
},
{
name: 'Learning/Counseling',
text: '학습/상담'
},
{
name: 'Getjob',
text: '취창업'
}
];
const CategoriesBlock = styled.div`
display: "flex",
padding: "10px",
flexDirection : "row",
margin: "0 auto"
`;
const Category = styled.div`
fontSize : "16px",
cursor : "pointer",
textDecoration: 'none'
& : hover = {
color : #0bb286;
}
& + & {
margin-left : 10px;
}
`;
const Categories = () => {
return (
<CategoriesBlock>
{categories.map(c => (
<Category key={c.name}>{c.text}</Category>
))}
</CategoriesBlock>
);
}
export default Categories;
I've checked at least 10 times that the module is at this location ./src/components/MainTemplate.
Yet, React still throws this error:
./src/components/MainTemplate.js
Module not found: Can't resolve './components/Categories' in '/workspace/web_platform_test/myapp/src/components'
if your MainTemplate.js is located at ./src/components/MainTemplate.js, and your Categories.js is located at ./src/components/Categories.js
Then your import statement should be: import Categories from './Categories';
Looks like you're importing from ./src/components' so update the import to import Categories from './Categories', i.e. remove components from your import.
I am creating a menu for an Android TV, the Menu expands when it get focus, but when moving from one menu item to the other I get a flicker because I can't find a way to make the menu focus independent from the menu item focus.
I've tried to use a Touchable around the Flat list but then i cant move focus to the items.
import { FlatList, StyleSheet, Text, TouchableHighlight, View } from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import { MaterialIcons } from '#expo/vector-icons';
import React from 'react';
interface MenuListOption {
name: string;
icon: string;
}
interface MenuItemProps {
setMenuFocus: (v: boolean) => void;
item: MenuListOption;
menuFocus: boolean;
}
export const homeLists: MenuListOption[] = [
{
name: 'HOME',
icon: 'home-filled',
},
{
name: 'MOVIES',
icon: 'local-movies',
},
{
name: 'TV SHOWS',
icon: 'movie',
},
];
const MenuItem = ({ setMenuFocus, item, menuFocus }: MenuItemProps): JSX.Element => {
const [focus, setFocus] = React.useState(false);
const onFocus = React.useCallback(() => {
setFocus(true);
setMenuFocus(true);
}, [setMenuFocus]);
const onBlur = React.useCallback(() => {
setFocus(false);
setMenuFocus(false);
}, [setMenuFocus]);
return (
<TouchableHighlight onFocus={onFocus} onBlur={onBlur} style={[styles.item, focus ? styles.itemFocused : null]}>
<View style={styles.itemWrapper}>
<MaterialIcons name={item.icon} size={50} color="red" />
{menuFocus && <Text style={styles.text}>{item.name}</Text>}
</View>
</TouchableHighlight>
);
};
const Menu = (): JSX.Element => {
const [focus, setFocus] = React.useState(false);
const colorsArray = focus ? ['gray', 'gray', 'transparent'] : ['gray', 'gray'];
const renderItem = ({ item }: { item: MenuListOption }) => (
<MenuItem setMenuFocus={setFocus} item={item} menuFocus={focus} />
);
return (
<View style={[styles.wrapper, focus ? styles.wrapperFocused : null]}>
<LinearGradient colors={colorsArray} start={{ x: 0, y: 0.9 }} end={{ x: 1, y: 0.9 }}>
<View style={focus ? styles.logoFocus : styles.logo}>
{focus && <MaterialIcons style={{ paddingRight: 20 }} name={'tv'} size={40} color={'white'} />}
<Text style={[styles.title, focus && styles.textFocus]}>MyApp</Text>
</View>
<FlatList
contentContainerStyle={{ justifyContent: 'center', flex: 1 }}
style={styles.list}
data={homeLists}
renderItem={renderItem}
keyExtractor={(item) => String(item.name)}
/>
</LinearGradient>
</View>
);
};
const styles = StyleSheet.create({
wrapper: {
height: '100%',
position: 'absolute',
top: 0,
zIndex: 1,
left: -200,
transform: [{ translateX: 200 }],
},
title: {
fontSize: 15,
lineHeight: 38,
fontWeight: '400',
textAlign: 'left',
},
wrapperFocused: {
width: 900,
},
logo: {
justifyContent: 'center',
flexDirection: 'row',
marginTop: 20,
},
list: {
flexGrow: 0,
height: '100%',
padding: 10,
},
logoFocus: {
justifyContent: 'flex-start',
flexDirection: 'row',
marginTop: 60,
marginLeft: 20,
},
textFocus: {
fontSize: 35,
},
item: {
maxWidth: 250,
marginBottom: 40,
alignSelf: 'stretch',
left: 0,
padding: 10,
},
itemFocused: {
borderBottomColor: 'yellow',
borderBottomWidth: 5,
},
itemWrapper: {
maxWidth: 250,
flexDirection: 'row',
},
text: {
color: 'white',
fontSize: 28,
lineHeight: 41,
fontWeight: '600',
marginLeft: 50,
marginTop: 5,
},
});
export default Menu;
Here is an animation of the problem:
menu