Selectable states in react-simple-maps - reactjs

I'm creating a map using react-simple-maps librery
this is my code so far
<ComposableMap
style={{ backgroundColor: "white", }}
projection="geoAlbers"
fill={'rgb(185,185,185)'}
projectionConfig={{
center:[-5, 25]
}}>
<Geographies style={{backgroundColor:'green', bottom:100}} geography={geoUrl}>
{({ geographies }) =>
geographies.map(geo => (
<Geography key={geo.rsmKey} geography={geo} />
))
}
</Geographies>
<Marker coordinates={[-100.460846,25.649345]}>
<g
fill="none"
stroke="#003DA5"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
transform="translate(-12, -24)"
>
<circle cx="12" cy="10" r="3" />
<path d="M12 21.7C17.3 17 20 13 20 10a8 8 0 1 0-16 0c0 3 2.7 6.9 8 11.7z" />
</g>
</Marker>
</ComposableMap>
but is there any way to get rid off of this border when you select a state ?

You can do that, passing the style attribute on <Geography />.
<ComposableMap>
<Geographies geography={geoUrl}>
{({ geographies }) =>
geographies.map(geo => <Geography style={{
default: { outline: "none" },
hover: { outline: "none" },
pressed: { outline: "none" },
}} key={geo.rsmKey} geography={geo} />)
}
</Geographies>
</ComposableMap>

Related

MUI React How to properly make a language dropdown

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;```

Why doesn't svg file work in react-native?

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

How to make a line break in svg

I have the following SVG of dynamically rendered pie chart using react-minimal-pie-chart :-
<svg viewBox="0 0 100 100" width="100%" height="100%"><path d="M 75 50 A 25 25 0 0 1 54.34120444167326 74.6201938253052" fill="none" stroke-width="50" stroke="#8dcd81"><title>Excellent</title></path><path d="M 54.34120444167326 74.6201938253052 A 25 25 0 0 1 26.507684480352285 41.449496416858295" fill="none" stroke-width="50" stroke="#eefa6b"><title>Good</title></path><path d="M 26.507684480352285 41.449496416858295 A 25 25 0 0 1 75 49.99999999999999" fill="none" stroke-width="50" stroke="#FF6382"><title>Weak</title></path><text dominant-baseline="central" x="50" y="50" dx="19.151111077974452" dy="16.06969024216348" text-anchor="middle" style="font-size: 5px;">22 %Excellent</text><text dominant-baseline="central" x="50" y="50" dx="-19.15111107797445" dy="16.069690242163485" text-anchor="middle" style="font-size: 5px;">33 %Good</text><text dominant-baseline="central" x="50" y="50" dx="4.341204441673249" dy="-24.620193825305204" text-anchor="middle" style="font-size: 5px;">44 %Weak</text></svg>
This is my Reactjs code:-
const Element = (props) => {
return (
<text
dominant-baseline="central"
x={props.x}
y={props.y}
dx={props.dx}
dy={props.dy}
text-anchor="middle"
style={{ fontSize: "5px" }}
>
{`${Math.round(props.dataEntry.percentage)} %`}
{props.dataEntry.title}
</text>
);
};
This is codesandbox full Reactjs example:-
https://codesandbox.io/s/throbbing-moon-ejs67?file=/src/App.js
How can i line break between the texts (excellent - good ..) and their percentage .
As Danny says - just stick in a tspan. These settings seem to work ok:
const Element = (props) => {
return (
<text
dominant-baseline="central"
x={props.x}
y={props.y}
dx={props.dx}
dy={props.dy}
text-anchor="middle"
style={{ fontSize: "5px" }}
>
{`${Math.round(props.dataEntry.percentage)} %`}
<tspan dx="-12" dy="5">
{props.dataEntry.title}
</tspan>
</text>
);
};

Firefox does not animate when <g> component attributes change

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

React: Trying to choose which source of truth and state management solution is most efficient for this scenario

I am trying to decide what state management solution to choose. I don't think I need Redux yet, maybe Context API or local storage can do the trick or maybe another proposition. All I simply need is for the states of my tabs to be directly connected to their directed URL upon clicking on them, AND for the state to persist upon refreshing the page. Of course, that means that as long as the URL has a certain string that the state will update to the related value of the Tab, that would also secure the state value when a link directing the user to that URL is clicked on.
I hope I was clear enough, thank you for taking the time to read this.
Here are the imports:
import React from 'react';
import AppBar from '#material-ui/core/AppBar';
import CssBaseline from '#material-ui/core/CssBaseline';
import Drawer from '#material-ui/core/Drawer';
import Hidden from '#material-ui/core/Hidden';
import IconButton from '#material-ui/core/IconButton';
import MenuIcon from '#material-ui/icons/Menu';
import Toolbar from '#material-ui/core/Toolbar';
import Typography from '#material-ui/core/Typography';
import {withStyles } from '#material-ui/core/styles';
import SearchBar from '../TopBar/SearchBar'
import Home from '../Screens/Home'
import Contact from '../Screens/Contact'
import Profile from '../Screens/Profile'
import Settings from '../Screens/Settings'
import Messages from '../Screens/Messages'
import Products from '../Screens/Products'
import Tabs from "#material-ui/core/Tabs";
import Tab from "#material-ui/core/Tab";
import { Switch, Route, Link, BrowserRouter} from "react-router-dom";
Drawer variable holding the tab structure:
const drawer = (
<Route
path="/"
render={() => (
<nav>
<div style={{ left: 70, position: 'relative', marginTop: 40 }}>
<VerticalTabs
value={values}
variant="fullWidth"
onChange={this.handleChange}
>
<MyTab
component={Link}
to="/"
disableRipple={widthS < 599 ? true : false}
onClick={this.handleDrawerToggle}
icon={
<svg
version="1.1"
id="Capa_1"
xmlns="http://www.w3.org/2000/svg"
xlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
width="460.298px"
height="460.297px"
viewBox="0 0 460.298 460.297"
space="preserve"
fill={values === 0 ? '#0D9DCE' : '#9B9B9B'}
className="home"
>
{homeA}
{homeB}
</svg>
}
label={
<p
className="home-Text"
style={{ color: values === 0 ? 'white' : '#9B9B9B' }}
>
Home
</p>
}
/>
<MyTab
component={Link}
to="/Screens/Contact"
disableRipple={widthS < 599 ? true : false}
onClick={this.handleDrawerToggle}
icon={
<svg
height="512pt"
viewBox="0 0 512 512"
width="512pt"
xmlns="http://www.w3.org/2000/svg"
fill={values === 1 ? '#0D9DCE' : '#9B9B9B'}
className="processes"
>
{ContactA}
</svg>
}
label={
<p
className="processes-Text"
style={{ color: values === 1 ? 'white' : '#9B9B9B' }}
>
Contact
</p>
}
/>
<MyTab
component={Link}
to="/Screens/Profile"
disableRipple={widthS < 599 ? true : false}
onClick={this.handleDrawerToggle}
icon={
<svg
version="1.1"
id="Capa_1"
xmlns="http://www.w3.org/2000/svg"
xlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
viewBox="0 0 512.001 512.001"
space="preserve"
className="designs"
fill={values === 2 ? '#0D9DCE' : '#9B9B9B'}
>
{ProfileA}
</svg>
}
label={
<p
className="designs-Text"
style={{ color: values === 2 ? 'white' : '#9B9B9B' }}
>
Profile
</p>
}
/>
<MyTab
component={Link}
to="/Screens/Settings"
disableRipple={widthS < 599 ? true : false}
onClick={this.handleDrawerToggle}
icon={
<svg
version="1.1"
id="Capa_1"
xmlns="http://www.w3.org/2000/svg"
xlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
viewBox="0 0 512 512"
space="preserve"
className="materials"
fill={values === 3 ? '#0D9DCE' : '#9B9B9B'}
>
{SettingsA}
{SettingsB}
</svg>
}
label={
<p
className="materials-Text"
style={{ color: values === 3 ? 'white' : '#9B9B9B' }}
>
Settings
</p>
}
/>
<MyTab
component={Link}
to="/Screens/Messages"
disableRipple={widthS < 599 ? true : false}
onClick={this.handleDrawerToggle}
icon={
<svg
xmlns="http://www.w3.org/2000/svg"
xlink="http://www.w3.org/1999/xlink"
width="512"
height="512"
viewBox="0 0 60 60"
version="1.1"
className="printers"
fill={values === 4 ? '#0D9DCE' : '#9B9B9B'}
>
{MessagesA}
{MessagesB}
{MessagesC}
{MessagesD}
{MessagesE}
{MessagesF}
</svg>
}
label={
<p
className="printers-Text"
style={{ color: values === 4 ? 'white' : '#9B9B9B' }}
>
Messages
</p>
}
/>
<MyTab
component={Link}
to="/Screens/Products"
disableRipple={widthS < 599 ? true : false}
onClick={this.handleDrawerToggle}
icon={
<svg
height="512pt"
viewBox="0 0 512 512"
width="512pt"
xmlns="http://www.w3.org/2000/svg"
className="forum"
fill={values === 5 ? '#0D9DCE' : '#9B9B9B'}
>
{ProductsA}
{ProductsB}
{ProductsC}
</svg>
}
label={
<p
className="QA-Text"
style={{ color: values === 5 ? 'white' : '#9B9B9B' }}
>
Products
</p>
}
/>
</VerticalTabs>
</div>
</nav>
)}
/>
);
Here is the routing structure within BrowserRouter:
<Switch>
<Route path="/Screens/Contact" component{Contact} />
<Route path="/Screens/Profile" component={Profile} />
<Route path="/Screens/Settings" component={Settings} />
<Route path="/Screens/Messages" component={Messages} />
<Route path="/Screens/Products" component={Products} />
<Route path="/" component={Home} />
</Switch>

Resources