I'm new to react with Typescript & MUI.
I'm working on a project that was originally built by someone else.
I need to modify an existing code and turn it into a <Autocomplete /> dropdownlist
Can someone please help with this?
I'm not really sure how to do this and I have been working on this for hours.
So basiclly the code below is working fine, I just need to make some changes to wrap the Language list in a dropdown list.
Currently it is working more like a dropdown menu.
const { borderRadius, locale, onChangeLocale } = useConfig();
const theme = useTheme();
const matchesXs = useMediaQuery(theme.breakpoints.down('md'));
const [open, setOpen] = useState(false);
const anchorRef = useRef<any>(null);
const [language, setLanguage] = useState<string>(locale);
const handleListItemClick = (
event:
| React.MouseEvent<HTMLAnchorElement>
| React.MouseEvent<HTMLDivElement, MouseEvent>
| undefined,
lng: string
) => {
setLanguage(lng);
onChangeLocale(lng);
setOpen(false);
};
const handleToggle = () => {
setOpen(prevOpen => !prevOpen);
};
const handleClose = (event: MouseEvent | TouchEvent) => {
if (anchorRef.current && anchorRef.current.contains(event.target)) {
return;
}
setOpen(false);
};
const prevOpen = useRef(open);
useEffect(() => {
if (prevOpen.current === true && open === false) {
anchorRef.current.focus();
}
prevOpen.current = open;
}, [open]);
useEffect(() => {
setLanguage(locale);
}, [locale]);
return (
<>
<Box
sx={{
ml: 3,
mr: 2,
[theme.breakpoints.down('md')]: {
ml: 1,
},
}}
>
<Avatar
variant="rounded"
sx={{
...theme.typography.commonAvatar,
...theme.typography.mediumAvatar,
border: '1px solid',
borderColor: 'rgba(255,255,255, 0)',
background: 'rgba(255,255,255, 0)',
color: theme.palette.primary.dark,
transition: 'all .2s ease-in-out',
'&[aria-controls="menu-list-grow"],&:hover': {
color: theme.palette.primary.main,
},
}}
ref={anchorRef}
aria-controls={open ? 'menu-list-grow' : undefined}
aria-haspopup="true"
onClick={handleToggle}
color="inherit"
>
{language !== 'en' && (
<Typography
variant="h2"
color="inherit"
sx={{ textTransform: 'uppercase', fontWeight: '500' }}
>
{language}
</Typography>
)}
{language === 'en' && (
<TranslateTwoToneIcon sx={{ fontSize: '2.2rem' }} />
)}
</Avatar>
</Box>
<Popper
placement={matchesXs ? 'bottom-start' : 'bottom'}
open={open}
anchorEl={anchorRef.current}
role={undefined}
transition
disablePortal
popperOptions={{
modifiers: [
{
name: 'offset',
options: {
offset: [matchesXs ? 0 : 0, 20],
},
},
],
}}
>
{({ TransitionProps }) => (
<ClickAwayListener onClickAway={handleClose}>
<Transitions
position={matchesXs ? 'top-left' : 'top'}
in={open}
{...TransitionProps}
>
<Paper elevation={16}>
{open && (
<List
component="nav"
sx={{
width: '100%',
minWidth: 200,
maxWidth: 280,
bgcolor: theme.palette.background.paper,
borderRadius: `${borderRadius}px`,
[theme.breakpoints.down('md')]: {
maxWidth: 250,
},
}}
>
<ListItemButton
selected={language === 'en'}
onClick={event => handleListItemClick(event, 'en')}
>
<ListItemText
primary={
<Grid container>
<Typography color="textPrimary">English</Typography>
<Typography
variant="caption"
color="textSecondary"
sx={{ ml: '8px' }}
>
(UK)
</Typography>
</Grid>
}
/>
</ListItemButton>
<ListItemButton
selected={language === 'sv'}
onClick={event => handleListItemClick(event, 'sv')}
>
<ListItemText
primary={
<Grid container>
<Typography color="textPrimary">Svenska</Typography>
<Typography
variant="caption"
color="textSecondary"
sx={{ ml: '8px' }}
>
(SE)
</Typography>
</Grid>
}
/>
</ListItemButton>
</List>
)}
</Paper>
</Transitions>
</ClickAwayListener>
)}
</Popper>
</>
);
};
export default LocalizationSection;```
I dont have any error, but it doesnt work.
I have a Search bar on the screen. Before the placeholder, i want to show a search icon there. As I know, I did what i needed to get this worked. I installed npm install react-native-svg --save and npm install react-native-svg-transformer --save And I added new code into metro.config.js But there must be something missing as it doesnt work.
Here is App.js
import React from 'react';
import { StyleSheet, Text, View, TextInput } from 'react-native';
import Search from "./src/icons/search.svg";
const App = () => {
return (
<View style={styles.container}>
<View style={styles.firstPart}>
<Text style={styles.date}>Saturday, Feb 21</Text>
<View style={styles.package}>
<Text style={styles.packageText}>Your Package</Text>
<View style={styles.plusIcon}>
<Text style={styles.textPlus}>+</Text>
</View>
<Search width={120} height={40} />
</View>
<TextInput style={styles.input} placeholder="Search" placeholderTextColor="gray"></TextInput>
</View>
</View>
);
};
const styles = StyleSheet.create({
container:{
margin:10,
},
firstPart:{
backgroundColor: "mediumblue",
borderTopRightRadius:40,
borderTopLeftRadius:40,
padding:20,
},
date:{
fontSize:15,
color:"white",
},
package:{
flexDirection: "row",
justifyContent: "space-between",
},
packageText: {
fontSize:25,
color:"white",
flexDirection: "column",
},
plusIcon: {
height:25,
width:25,
borderRadius:25,
backgroundColor:"blue",
marginTop:5,
},
textPlus: {
fontSize:25,
fontWeight:"bold",
color:"white",
marginLeft:5,
},
input: {
height:40,
borderWidth:.5,
borderRadius:10,
marginVertical:10,
}
});
export default App;
metro.config.js
/**
* Metro configuration for React Native
* https://github.com/facebook/react-native
*
* #format
*/
module.exports = {
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
}),
},
};
const { getDefaultConfig } = require("metro-config");
module.exports = (async () => {
const {
resolver: { sourceExts, assetExts }
} = await getDefaultConfig();
return {
transformer: {
babelTransformerPath: require.resolve("react-native-svg-transformer")
},
resolver: {
assetExts: assetExts.filter(ext => ext !== "svg"),
sourceExts: [...sourceExts, "svg"]
}
};
})();
src/icons/search.svg
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
<g>
<path d="M310,190c-5.52,0-10,4.48-10,10s4.48,10,10,10c5.52,0,10-4.48,10-10S315.52,190,310,190z"/>
</g>
</g>
<g>
<g>
<path d="M500.281,443.719l-133.48-133.48C388.546,277.485,400,239.555,400,200C400,89.72,310.28,0,200,0S0,89.72,0,200
s89.72,200,200,200c39.556,0,77.486-11.455,110.239-33.198l36.895,36.895c0.005,0.005,0.01,0.01,0.016,0.016l96.568,96.568
C451.276,507.838,461.319,512,472,512c10.681,0,20.724-4.162,28.278-11.716C507.837,492.731,512,482.687,512,472
S507.837,451.269,500.281,443.719z M305.536,345.727c0,0.001-0.001,0.001-0.002,0.002C274.667,368.149,238.175,380,200,380
c-99.252,0-180-80.748-180-180S100.748,20,200,20s180,80.748,180,180c0,38.175-11.851,74.667-34.272,105.535
C334.511,320.988,320.989,334.511,305.536,345.727z M326.516,354.793c10.35-8.467,19.811-17.928,28.277-28.277l28.371,28.371
c-8.628,10.183-18.094,19.65-28.277,28.277L326.516,354.793z M486.139,486.139c-3.78,3.78-8.801,5.861-14.139,5.861
s-10.359-2.081-14.139-5.861l-88.795-88.795c10.127-8.691,19.587-18.15,28.277-28.277l88.798,88.798
C489.919,461.639,492,466.658,492,472C492,477.342,489.919,482.361,486.139,486.139z"/>
</g>
</g>
<g>
<g>
<path d="M200,40c-88.225,0-160,71.775-160,160s71.775,160,160,160s160-71.775,160-160S288.225,40,200,40z M200,340
c-77.196,0-140-62.804-140-140S122.804,60,200,60s140,62.804,140,140S277.196,340,200,340z"/>
</g>
</g>
<g>
<g>
<path d="M312.065,157.073c-8.611-22.412-23.604-41.574-43.36-55.413C248.479,87.49,224.721,80,200,80c-5.522,0-10,4.478-10,10
c0,5.522,4.478,10,10,10c41.099,0,78.631,25.818,93.396,64.247c1.528,3.976,5.317,6.416,9.337,6.416
c1.192,0,2.405-0.215,3.584-0.668C311.472,168.014,314.046,162.229,312.065,157.073z"/>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>
I just used your svg file to see if it works and it is visible only if you set a fill property to it.
Like this
<Search width={120} height={40} fill={"#00FF00"}/>
// Putting the icon inside text field; sorry for the inline styling
<View
style={{position: 'absolute', top: 10, zIndex: 20}}
>
<Search height={30} width={30} fill={"#00FF00"}/>
</View>
<TextInput
style={{backgroundColor: 'orange', height: 50, paddingLeft: 50}} placeholder="Search" placeholderTextColor="gray"
/>
// You will have to change that top style in accordance to your layout of course
EDIT
As per my knowledge, that placeholder can only be a string. But anyway, you can obtain what you've said. You can have a state called, let's say isTextInputFocused which will become true when textInput is focused and false when it is blurred (implement onFocus & onBlur to change that state) and then,
{ !isTextInputFocused && ( <View
style={{position: 'absolute', top: 10, zIndex: 20}}
>
<Search height={30} width={30} fill={"#00FF00"}/>
</View> )}
Basically, conditionally display that image by a variable you manipulate
I'm creating some animated React components in SVG. When I run it in Chrome, the animation works, but when I run it in Firefox, it doesn't.
Here is an example:
const [x, setX] = useState(0)
useEffect(() => {
setTimeout(() => {
setX(100)
}, 3000)
}, [])
return (
<svg width={500} height={300}>
<g transform={`translate(${x}, ${0})`} style={{ transition: "3s all" }}>
<rect width={50} height={50} x={0} y={0} fill={'#f00'} />
</g>
</svg>
)
You can see that it works in Chrome, but not in Firefox: https://codesandbox.io/s/gracious-ives-ykmfp
If I remove the transform in g and change direct in x prop of the rect, that way will work in Firefox, but I don't want to do it that way.
Any help?
The transform attribute is not the same as the transform CSS property, even though it can be confusing (and apparently the two will be merged).
Instead of using the attribute, move the transform to the style property:
const [x, setX] = useState(0);
useEffect(() => {
setTimeout(() => {
setX(100);
}, 3000);
}, []);
return (
<svg width={500} height={300}>
<g style={{ transform: `translate(${x}px, 0px)`, transition: 'all 3s' }}>
<rect width={50} height={50} x={0} y={0} fill={'#f00'} />
</g>
</svg>
);
Demo: https://codesandbox.io/s/nifty-snowflake-664rk
Try to move the transform property to the style. It works for me this way in FF.:
<g style={{transform: `translateX(${x}px)`, transition: "3s all" }}>
<rect width={50} height={50} x={0} y={0} fill={"#f00"} />
</g>
https://codesandbox.io/s/musing-cdn-7eqg0