How do I make sidebar automatically disappear once a menu item clicked - reactjs

I implemented a some Sidebar code and would like the sidebar to automatically close once an item is clicked. Currently have to click the 'X' to hide sidebar. Below is the existing code for the Sidebar and Sidebar sub-menu.
Probably a one line fix if you know what you are doing, but I am new to React, so any help would be appreciated.
...
import React, { useState } from 'react';
import styled from 'styled-components';
import { Link } from 'react-router-dom';
import * as FaIcons from 'react-icons/fa';
import * as AiIcons from 'react-icons/ai';
import { SidebarData } from './SidebarData';
import SubMenu from './SubMenu';
import { IconContext } from 'react-icons/lib';
const Nav = styled.div`
// background: #15171c;
background: black;
height: 60px;
display: flex;
justify-content: flex-start;
align-items: center;
`;
const NavIcon = styled(Link)`
margin-left: 2rem;
font-size: 2rem;
height: 60px;
display: flex;
justify-content: flex-start;
align-items: center;
`;
// background: #15171c;
const SidebarNav = styled.nav`
background: #15171c;
width: 250px;
height: 150vh;
display: flex;
justify-content: center;
position: fixed;
top: 0;
left: ${({ sidebar }) => (sidebar ? '0' : '-100%')};
transition: 350ms;
z-index: 10;
`;
const SidebarWrap = styled.div`
width: 100%;
`;
const Sidebar = () => {
const [sidebar, setSidebar] = useState(false);
const showSidebar = () => setSidebar(!sidebar);
return (
<>
<IconContext.Provider value={{ color: '#fff' }}>
<Nav>
<NavIcon to='#'>
<FaIcons.FaBars onClick={showSidebar} />
</NavIcon>
</Nav>
<SidebarNav sidebar={sidebar}>
<SidebarWrap>
<NavIcon to='#'>
<AiIcons.AiOutlineClose onClick={showSidebar} />
</NavIcon>
{SidebarData.map((item, index) => {
return <SubMenu item={item} key={index} />;
})}
</SidebarWrap>
</SidebarNav>
</IconContext.Provider>
</>
);
};
export default Sidebar;
import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import styled from 'styled-components';
const SidebarLink = styled(Link)`
display: flex;
color: #e1e9fc;
justify-content: space-between;
align-items: center;
padding: 20px;
list-style: none;
height: 40px;
text-decoration: none;
font-size: 18px;
//#c6c8cf
//#252831
&:hover {
background: #c6c8cf;
border-left: 4px solid #632ce4;
cursor: pointer;
}
`;
const SidebarLabel = styled.span`
margin-left: 16px;
`;
const DropdownLink = styled(Link)`
background: #414757;
height: 40px;
padding-left: 3rem;
display: flex;
align-items: center;
text-decoration: none;
color: #f5f5f5;
font-size: 18px;
// background: #632ce4;
&:hover {
background: #d9dbd5;
cursor: pointer;
}
`;
const SubMenu = ({ item }) => {
const [subnav, setSubnav] = useState(false);
const showSubnav = () => setSubnav(!subnav);
return (
<>
<SidebarLink to={item.path} onClick={item.subNav && showSubnav}>
<div>
{item.icon}
<SidebarLabel>{item.title}</SidebarLabel>
</div>
<div>
{item.subNav && subnav
? item.iconOpened
: item.subNav
? item.iconClosed
: null}
</div>
</SidebarLink>
{subnav &&
item.subNav.map((item, index) => {
return (
<DropdownLink to={item.path} key={index}>
{item.icon}
<SidebarLabel>{item.title}</SidebarLabel>
</DropdownLink>
);
})}
</>
);
};
export default SubMenu;
import React from 'react';
// import * as FaIcons from 'react-icons/fa';
import * as AiIcons from 'react-icons/ai';
import * as IoIcons from 'react-icons/io';
import * as RiIcons from 'react-icons/ri';
import * as FaIcons from 'react-icons/fa';
export const SidebarData = [
{
title: 'Login',
path: '/login',
icon: <AiIcons.AiOutlineLogin />,
},
{
title: 'Site Master',
path: '/list-sitemaster',
icon: <FaIcons.FaBroadcastTower />,
},
{
title: 'Site Report Cards',
path: '/sitereportcardmaster',
icon: <IoIcons.IoIosPaper />,
},
{
title: 'Report Card Master',
path: '/reportcardmaster',
icon: <IoIcons.IoIosPaper />
},
{
title: 'Categories',
path: '/categories',
icon: <IoIcons.IoIosClipboard />,
iconClosed: <RiIcons.RiArrowDownSFill />,
iconOpened: <RiIcons.RiArrowUpSFill />,
subNav: [
{
title: 'Asset Type',
path: '/assettype',
icon: <IoIcons.IoIosPaper />,
cName: 'sub-nav'
},
{
title: 'Asset Sub Type',
path: '/assetsubtype',
icon: <IoIcons.IoIosPaper />,
cName: 'sub-nav'
},
{
title: 'Document Type',
path: '/documenttype',
icon: <IoIcons.IoIosPaper />,
cName: 'sub-nav'
},
{
title: 'Document Sub Type',
path: '/documentsubtype',
icon: <IoIcons.IoIosPaper />,
cName: 'sub-nav'
},
{
title: 'Report Card Category',
path: '/reportcarddetailcategory',
icon: <IoIcons.IoIosPaper />,
cName: 'sub-nav'
},
{
title: 'Contact Detail Type',
path: '/contactdetailtype',
icon: <IoIcons.IoIosPaper />,
cName: 'sub-nav'
},
{
title: 'Lighting Type',
path: '/lightingtype',
icon: <IoIcons.IoIosPaper />,
cName: 'sub-nav'
}
]
},
{
title: 'Company Master',
path: '/cpymaster-toplevel',
icon: <AiIcons.AiFillHome />,
iconClosed: <RiIcons.RiArrowDownSFill />,
iconOpened: <RiIcons.RiArrowUpSFill />,
subNav: [
{
title: 'CompanyMaster',
path: '/cpymaster',
icon: <AiIcons.AiFillHome />,
cName: 'sub-nav'
},
{
title: 'Users',
path: '/users',
icon: <IoIcons.IoIosPerson />,
cName: 'sub-nav'
},
{
title: 'Contacts',
path: '/contactmaster',
icon: <IoIcons.IoIosPeople />,
cName: 'sub-nav'
}
]
},
{
title: 'My Profile',
path: '/add-usersmall',
icon: <AiIcons.AiOutlineUser/>,
},
{
title: 'PDF',
path: '/pdfcomponent',
icon: <AiIcons.AiOutlineUser/>,
},
{
title: 'Users PageSort Test',
path: '/userstable',
icon: <AiIcons.AiOutlineUser/>,
},
{
title: 'Logout',
path: '/logout',
icon: <AiIcons.AiOutlineLogin />,
}
];
...

You have a state for the sidebar in
const Sidebar = () => {
const [sidebar, setSidebar] = useState(false);
const showSidebar = () => setSidebar(!sidebar);
...
If I'm not wrong, you close it in
<AiIcons.AiOutlineClose onClick={showSidebar} />
You can pass down that showSidebar function to the link components, somthing like
<SubMenu item={item} key={index} toggleSidebar={showSidebar}/>
(Also, avoid using index as key)
Receiving the funtion in the SubMenu component
const SubMenu = ({ item,toggleSidebar }) => {
thus, you are able to use it in the link

The following code in the subMenu.js along with #Daniel toggleSidebar code in sideBar.js rendered the desired results.
...
return (
<>
<SidebarLink to={item.path} onClick={item.subNav && showSubnav}>
<div>
{item.icon}
{/*following onClick={toggleSidebar} allows mainm menu items without subnav to close sidebar */}
<SidebarLabel onClick={toggleSidebar}>{item.title}</SidebarLabel>
</div>
<div>
{item.subNav && subnav
? item.iconOpened
: item.subNav
? item.iconClosed
: null}
</div>
</SidebarLink>
{subnav &&
item.subNav.map((item, index) => {
return (
//following onClick={toggleSidebar} allows submenu selections to close sidebar
<DropdownLink to={item.path} key={index} onClick={toggleSidebar}>
{item.icon}
<SidebarLabel>{item.title}</SidebarLabel>
</DropdownLink>
);
})}
</>
);
...

Related

Issue in removing Grandchild in a recursive component

What I have been trying to achieve?
Create a nested context menu that is driven by a config.
Where am I stuck:
Sub menus are rendering correctly, but if there is more than 2 level, the change in root level only affects its sub-menu and not its entire tree
Here is the sandbox link for you to check.
Steps to reproduce:
On load, a menu is displayed (say menu)
Click on File, it will open its sub menu (say sub-menu1).
Click on Open in the sub-menu1, again another sub menu (say sub-menu2) is open.
Now when you click on Edit in menu, sub-menu1 disappears but not sub-menu2
I think, I know the problem. sub-menu2 is not refreshing because props or state is not changed. To hide it, we will need to trickle down some prop but can't think of elegant way to do it without state management system.
You'll have a better time if the ContextMenu component is responsible for state management and recursion is flattened into iteration.
function ContextItem({ item, onClick }) {
return (
<div className="menu-item" onClick={() => onClick(item)}>
<p className="menu-title">{item.title}</p>
{item.children && item.children.length > 0 ? <i className="right-icon">{">"}</i> : null}
</div>
);
}
function MenuList({ list, onClick }) {
return (
<div className="menu-container">
{list.map((listItem) => (
<ContextItem item={listItem} key={listItem.title} onClick={onClick} />
))}
</div>
);
}
const ContextMenu = ({ list }) => {
const [openSubmenus, setOpenSubmenus] = React.useState([]);
const clickHandler = React.useCallback((item, level) => {
if (item.children && item.children.length) {
setOpenSubmenus((oldItems) => {
return [...oldItems.slice(0, level), item.children];
});
} else {
setOpenSubmenus([]); // item selected, clear submenus
alert(item.title);
}
}, []);
const menus = [list, ...openSubmenus];
return (
<div className="menu">
{menus.map((menu, level) => (
<MenuList
key={level}
list={menu}
level={level}
onClick={(item) => clickHandler(item, level)}
/>
))}
</div>
);
};
const menuList = [{
title: "File",
children: [{
title: "Close",
children: [],
action: "fileClose",
}, {
title: "Open",
children: [{
title: "A:\\",
children: [],
action: "",
}, {
title: "C:\\",
children: [],
action: "",
}, {
title: "\\",
children: [],
action: "",
}],
action: "",
}, {
title: "Find",
children: [{
title: "here",
children: [],
}, {
title: "elsewhere",
children: [],
}],
action: "",
}, {
title: "Backup",
children: [],
action: "backup",
}],
action: "",
}, {
title: "Edit",
children: [],
action: "edit",
}];
function App() {
return <ContextMenu list={menuList} />;
}
ReactDOM.render(<App />, document.getElementById("root"));
.menu {
display: flex;
flex-direction: row;
}
.menu-container {
display: flex;
flex-direction: column;
background-color: #eee;
border: 1px solid gray;
border-radius: 4px;
}
.menu-item {
display: flex;
flex-direction: row;
margin: 2px;
max-width: 200px;
line-height: 30px;
padding: 5px 10px;
}
.menu-title {
min-width: 80px;
height: 30px;
flex-grow: 1;
margin: 0;
vertical-align: middle;
}
.menu-title.active {
background-color: blue;
color: white;
}
.right-icon {
width: 25px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.0.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>
You could use the label as the key to reset the ContextMenu state when selectedItem change (assuming the label is unique at a given depth, but it seems reasonable, otherwise you could add unique ids).
export const ContextMenu = ({list}) => {
const [selectedItem, setSelectedItem] = useState();
return (
<div className="menu">
<div className="menu-container">
{list.map((listItem) => {
return (
<ContextItem
item={listItem}
key={listItem.title}
onClick={setSelectedItem}
/>
);
})}
</div>
{selectedItem?.children.length > 0 && <ContextMenu
key={selectedItem.title}
list={selectedItem.children}/>}
</div>
);
};

How can I style active Link ,if i have Grid material-ui

I have Grids from material-ui, when you click on it, the link changes,when i want to change text color to black.
Please tell me how to get a different text color if the link is active
I just don't want to use NavLink.Who had such a problem I know if you use NavLink then you can get a different color through activeStyle
export const gridLayoutChildCSS = css`
&& {
height: 64px;
width: 100%;
&:hover {
background-color: ${(props) => props.theme.colors.grey};
transition: 0.1s ease-in-out;
}
cursor: pointer;
}
`;
export const gridLayoutIconCSS = css`
&& {
height: 26px;
}
`;
export const gridLayoutChildTextCSS = css`
&& {
font-family: Fira Sans;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 24px;
letter-spacing: 0.02em;
text-align: left;
color: ${(props) => props.theme.colors.wetAsphalt};
}
`;
export const Sidebar: React.FC = () => {
const [isLoading, setIsLoading] = useState(false);
const handleRedirect = useHandleRedirect();
const topItems = [
{ icon: <SvgCalendarIcon />, title: 'Пункт', url: NEW_PATHS.welcome.main },
{ icon: <SvgDocumentsIcon />, title: 'Список документов', url: '' },
{ icon: <SvgCalendarIcon />, title: 'График работы', url: '' },
{ icon: <SvgPeopleIcon />, title: 'Сотрудники', url: '' },
];
const bottomItems = [
{ icon: <SvgQuestionIcon />, title: 'Помощь', url: '' },
{ icon: <SvgProfileIcon />, title: 'Профайл', url: '' },
{ icon: <SvgSettingsIcon />, title: 'Настройки', url: '' },
];
return (
<Styled.Root>
{isLoading ? (
<OldSidebar />
) : (
{topItems.map((topItem) => {
return (
<Grid
css={gridLayoutChildCSS}
onClick={() => handleRedirect(topItem.url)}
container
direction="row"
justifyContent="center"
alignItems="center"
>
<Grid css={gridLayoutIconCSS} item xs={2}>
{topItem.icon}
</Grid>
<Grid item xs={7}>
<Typography css={gridLayoutChildTextCSS}>{topItem.title}</Typography>
</Grid>
</Grid>
);
})}
)}
</Styled.Root>
);
};
set [isactive,setIsactive] state and when clicked set isactive to true and change the classname when isactive is true

React Data-Table search component not rendering/working like it should

I am using an npm package called react-datatable for a project and I am trying to build out a way to search through the data. I found a repo where someone was able to do this; however, his react skills are above mine and I cannot seem to make his code work properly on my end. I would just like to know why it isn't rendering anything on my front end. Any advice would be helpful. Thank you.
His code:
import React from 'react';
import styled from 'styled-components';
import { storiesOf } from '#storybook/react';
import faker from 'faker';
import Button from '../shared/Button';
import DataTable from '../../../src/index';
const createUser = () => ({
id: faker.random.uuid(),
name: faker.name.findName(),
email: faker.internet.email(),
address: faker.address.streetAddress(),
bio: faker.lorem.sentence(),
image: faker.image.avatar(),
});
const createUsers = (numUsers = 5) =>
new Array(numUsers).fill(undefined).map(createUser);
const fakeUsers = createUsers(2000);
const TextField = styled.input`
height: 32px;
width: 200px;
border-radius: 3px;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border: 1px solid #e5e5e5;
padding: 0 32px 0 16px;
&:hover {
cursor: pointer;
}
`;
const ClearButton = styled(Button)`
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
height: 34px;
width: 32px;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
`;
const FilterComponent = ({ filterText, onFilter, onClear }) => (
<>
<TextField id="search" type="text" placeholder="Filter By Name" aria-label="Search Input" value={filterText} onChange={onFilter} />
<ClearButton type="button" onClick={onClear}>X</ClearButton>
</>
);
const columns = [
{
name: 'Name',
selector: 'name',
sortable: true,
},
{
name: 'Email',
selector: 'email',
sortable: true,
},
{
name: 'Address',
selector: 'address',
sortable: true,
},
];
const BasicTable = () => {
const [filterText, setFilterText] = React.useState('');
const [resetPaginationToggle, setResetPaginationToggle] = React.useState(false);
const filteredItems = fakeUsers.filter(item => item.name && item.name.toLowerCase().includes(filterText.toLowerCase()));
const subHeaderComponentMemo = React.useMemo(() => {
const handleClear = () => {
if (filterText) {
setResetPaginationToggle(!resetPaginationToggle);
setFilterText('');
}
};
return <FilterComponent onFilter={e => setFilterText(e.target.value)} onClear={handleClear} filterText={filterText} />;
}, [filterText, resetPaginationToggle]);
return (
<DataTable
title="Contact List"
columns={columns}
data={filteredItems}
pagination
paginationResetDefaultPage={resetPaginationToggle} // optionally, a hook to reset pagination to page 1
subHeader
subHeaderComponent={subHeaderComponentMemo}
selectableRows
persistTableHead
/>
);
};
storiesOf('Filtering', module)
.add('Example 1', () => <BasicTable />)
My code:
import React from 'react';
import NotesListHtml from './NoteListHtml'
import DataTable from 'react-data-table-component';
const FilterComponent = ( { filterText, onClear, onFilter }) => (
<>
<input id="search" type="text" placeholder="Filter By Name" aria-label="Search Input" value={filterText} onChange={onFilter} />
<button type="button" onClick={onClear}>X</button>
</>
)
const BasicTable = (props) => {
let result = props.notes.map(function(el) {
var o = Object.assign({}, el);
o.fullName = `${props.data.first_name} ${props.data.last_name}`;
return o;
})
const ExpandableComponent = ({ data }) =>{
return(<p style={{padding:'20px'}}>{data.contentBody}</p>)
}
const columns = [
{
name: 'Organization',
selector: row => row.type[0].label || row.type,
sortable: true,
wrap:true
},
{
name: 'Title',
selector: 'title',
sortable: true,
},
{
name: 'Date',
selector: row=>row.createdAt.split('T')[0],
sortable: true,
},
{
name: 'Author',
selector: 'fullName',
sortable: true,
},
];
const customStyles = {
headCells: {
style: {
backgroundColor:'#f3f7f9',
},
},
cells: {
style: {
color:'#79838b'
},
},
};
const [filterText, setFilterText] = React.useState('');
const [resetPaginationToggle, setResetPaginationToggle] = React.useState(false);
const filteredItems = props.notes.filter(item => item.type[0].label && item.type[0].label.toLowerCase().includes(filterText.toLowerCase()))
const subHeaderComponentMemo = React.useMemo(() => {
console.log('subheader')
const handleClear = () => {
console.log('hit1')
if (filterText) {
setResetPaginationToggle(!resetPaginationToggle);
setFilterText('');
}
}
console.log('beforereturn');
return (
<>
{/* <input id="search" type="text" placeholder="Filter By Name" aria-label="Search Input" value={filterText} onChange={onFilter} /> */}
<button type="button" onClick={handleClear}>X</button>
</>
)
}, [filterText, resetPaginationToggle])
return (
<>
<DataTable
subHeaderComponent={subHeaderComponentMemo}
className='table'
columns={columns}
data={filteredItems}
pagination={true}
highlightOnHover={true}
pointerOnHover={true}
expandableRows={true}
expandOnRowClicked={true}
expandableRowsComponent={<ExpandableComponent data={result} />}
paginationResetDefaultPage={resetPaginationToggle} // optionally, a hook to reset pagination to page 1
customStyles={customStyles}
subHeader={false}
/>
</>
);
}
export default BasicTable;

React-select, open sub-menu when hover over an option

I'm trying to build a submenu inside a main menu with React-select, it should be something like this:
When hovering over an option from the main menu, it triggers the submenu to open at the side.
Is there a way to do this using react-select? I couldn't find any example or documentation on this, is there a function like ```optionOnMouseover`` for this? Thank you in advance!
const options = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' },
];
...
<Select
value={...}
onChange={...}
options={options}
/>```
This is on click, but if you need on hover,
just modify it
import React, { useState } from "react";
import ReactDOM from "react-dom";
import Select, { components } from "react-select"
const CustomOption = (props) => {
const [submenu, setSubmenu] = useState(false)
const [height, setHeight] = useState(0)
const handleOption = (e) => {
if(submenu) {
setSubmenu(false)
} else {
setHeight(e.clientY)
setSubmenu(true)
}
}
const handleSubOption = (e) => {
console.log('clicked')
}
const { data } = props;
return data.custom ? (
<>
<div onClick={handleOption} className="customs">
{data.label} <span className="caret"/>
{
submenu && (
<div className="dropdown-submenu">
<div className="drops" onClick={handleSubOption}>
Test dropdown 1
</div>
<div className="drops" onClick={handleSubOption}>
Test dropdown 2
</div>
<div className="drops" onClick={handleSubOption}>
Test dropdown 3
</div>
</div>
)
}
</div>
<style jsx>{`
.customs {
height: 36px;
padding: 8px;
position: relative;
}
.drops {
height: 36px;
padding: 8px;
}
.customs:hover, .drops:hover {
background-color: #17cf76;
}
.dropdown-submenu {
position: fixed;
top: ${height - 10}px;
left: 410px;
min-height: 36px;
overflow: auto;
border: 1px solid hsl(0,0%,80%);
border-radius: 4px;
color: #212529;
}
`}</style>
</>
) : (
<components.Option {...props} />
);
};
const options = [
{ custom: true, label: "I'm a custom link", value: "cust" }
];
function App() {
return (
<>
<Select classNamePrefix="category-select" className="w-30" components={{ Option: CustomOption }} options={options} />
<style jsx global>{`
* {
font-family: sans-serif;
text-align: center;
}
.w-30 {
width: 30% !important;
}
`}</style>
</>
)
}
export default App

react map leaflet circleMarker doesn't render

I have a leaflet map, and I have one button. I want to display some circlesMarker when I click on a button and remove the circlesMarker when I click again (remove option is not implemented yet)
I don't want to render each time all map when I click the button, I want render only the circleMarker.
CircleMarker doesn't render on a map, but I can see the map
Here my code :
COMPONENT MAP
function Map1() {
const apartments = [
{ roomType: 'shared room', geometry: [41.402610, 2.204270] },
{ roomType: 'shared room', geometry: [41.411300, 2.217630] },
{ roomType: 'private room', geometry: [41.410220, 2.212520] },
{ roomType: 'apartament sencer', geometry: [41.410630, 2.216970] },
{ roomType: 'private room', geometry: [41.409190, 2.209030] },
]
let map = useRef(null);
useEffect(() => {
let url = 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}'
const access = 'pk.eyJ1Ijoiam9zZXQyMSIsImEiOiJjazF1bGZlcHowYjVlM2RwYW9ia2pwaWtlIn0.9n-6tKArfdSfd15Do6YxLA'
map.current = L.map("map");
const defaultCenter = [41.383, 2.173];
const defaultZoom = 13.10;
let layer = L.tileLayer(url, {
maxZoom: 18,
id: 'mapbox.streets',
accessToken: access,
});
map.current.setView(defaultCenter, defaultZoom);
layer.addTo(map.current);
}, [map])
const handleOnclik = (e) => {
e.preventDefault()
let color = (e.target.name)
if (color === 'pink') {
apartments.map(item => {
if (item.roomType === 'private room' || item.roomType === 'shared room') {
return (
<div>
<p>Carme</p>
<CircleMarker className="circle"
center={[41.409190, 2.209030]}
color={'#000080'}
width={.5}
fillColor={'blue'}
fillOpacity={0.5}
stroke={'black'}
>
</CircleMarker >
</div>
)
}
})
}
return (<>
<div className="container">
<div>
<div id="map" className="normalscreen"></div>
</div>
<div id="basemaps-wrapper" className="leaflet-bar">
<select id="basemaps">
<option>Visualització</option>
<option value="mapbox.streets">Streets</option>
<option value="mapbox.satellite">Satellite</option>
<option value="mapbox.outdoors">Outdoors</option>
<option value="mapbox.dark">Dark</option>
<option value="mapbox.light">Light</option>
<option value="mapbox.DarkGray">Dark Gray</option>
</select>
<button onClick={onChangeFullScreen}>Full Screen</button>
<div>
<img onClick={handleOnclik} name="pink" src="images/pink" alt="habitacio" />
<img onClick={handleOnclik} name="green" src="images/green" alt="apartament" />
</div>
</div>
</div>
</>)
}
export default Map1
MAP CSS
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.container {
display: flex;
flex-direction: column;
width: 100vw;
justify-content: center;
}
#map {
display: block;
}
.normalscreen {
width: 50%;
height: 50vh;
left: 49%;
position: relative;
}
.fullscreen {
width: 100%;
height: 80vh;
left: 0%;
text-align: center;
}
APP
import React from 'react'
import { withRouter } from 'react-router-dom'
import Navbar from './Navbar'
import Map from './Map'
function App() {
return (<>
<Navbar />
<Map />
</>);
}
export default withRouter(App)
There is no CircleMarker component on leaflet library exposed unless you use react-leaflet which you don't. Therefore here is the code you need to use in order to add to the map circle markers:
const handleOnclik = () => {
apartments.forEach(({ geometry }) => {
new L.CircleMarker(geometry, {
radius: 5,
fillColor: "blue",
width: 0.5,
stroke: "black",
color: "#000080",
fillOpacity: 0.5
}).addTo(map.current);
});
};
I removed the if statements for simplicity just to illustrate an example.
Demo

Resources