I want to use this as a navigation for my page ,
but i cant find out how to Link in the index properly,
I already tried to put l the items apart but that didnt work
whit ,,
and
<List>
{['Home' , 'About', 'Services', 'Contact'].map((text, index) => (
<ListItem button key={text} >
<ListItemIcon>
{index === 0 && <HomeOutlinedIcon /> }
{index === 1 && <InfoOutlined/>}
{index === 2 && <SettingsOutlinedIcon />}
{index === 3 && <MailIcon/>}
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
Can someone, Show me how to correctly route my navigation in this list.
Just create pages for 'Home' , 'About', 'Services', 'Contact' and use the navigate function from reach-router.
You just have to declare your routes in the app.js with your path="/app/home" etc and the component you want to render to the DOM, then use navigate("/app/home") so you should change your array to an object with the good route on each item like this
const fieldsNames = [
{ value: "Home", icon: <SvgIcon component={SearchIcon} />, path: "/app/home" },
]
and map on those item with an onClick.
Related
What I'm trying to do is get which is the key of the sider the user is using (without ReactDOM and with functional components)
my sample code here:
export default function DrawerSider() {
const history = useHistory();
const [selectedKey, setSelectedKey] = useState("sub1")
const handleSelectKey = function(key, history_string) {
setSelectedKey(key)
history.push(history_string)
console.log(key)
}
return (
<Sider width={200} className="site-layout-background">
<Menu
defaultSelectedKeys={selectedKey}
mode="inline"
style={{ height: "100%", borderRight: 0 }}
>
<Menu.Item
key="sub1"
icon={<HomeOutlined />}
onClick={() => handleSelectKey("sub1","/dashboard/resumo")}
>
Dashboard
</Menu.Item>
<SubMenu key="sub2" icon={<UserOutlined />} title="Usuários">
<Menu.Item
key="1"
icon={<PlusCircleOutlined />}
onClick={() => handleSelectKey("1","/usuarios/novo")}
>
Adicionar usúario
</Menu.Item>
<Menu.Item
key="2"
icon={<TableOutlined />}
onClick={() => handleSelectKey("2","/usuarios/todos")}
>
Todos usúarios
</Menu.Item>
</SubMenu>
<SubMenu key="sub3" icon={<FormOutlined />} title="Formulários">
<Menu.Item
key="3"
icon={<PlusCircleOutlined />}
onClick={() => handleSelectKey("3","/formularios/novo")}
>
Adicionar formulário
</Menu.Item>
</SubMenu>
</SubMenu>
</Menu>
</Sider>
);
}
Obs: I'm using ant design lib
Someone knows how to make it works?
I tried to use a const on click event to set a state of the selected key , but it didn't work
There is no onClick on Menu.Item
only Menu component has onClick or onSelect, both will give you callback of the "clicked" key, the differences is onClick is for any menu item click (including expanding menu) while on select is when you select an actual menu item.
There are 2 ways to get the history string:
1 - use the history string as menuItem key:
the issue would be you cannot have 2 menu item that has same history key
2 - have a map which maps the menu key to history string
see below demo:
https://codesandbox.io/s/inline-menu-antd-4-18-2-forked-bgwyj?file=/index.js
const handleOnSelect = ({ item, key, keyPath, selectedKeys, domEvent }) => {
console.log(item);
console.log(keyPath);
console.log(selectedKeys);
console.log(domEvent);
handleSelectKey(key);
};
...
..
<Menu
onSelect={handleOnSelect}
...
>
...
</Menu>
You need to save the selected key as part of the component's state. You can set the current selected key as part of the onClick.
const selectedKey, setSelectedKey = useState("defaultSelectedKey")
Not sure what the useHistory hook is for but if you need to set that onClick as well as the selectedKey, move it all into one function like so
const handleSelectKey = function(key, history_string) {
setSelectedKey(key)
history.push(history_string)
}
...
onclick={() => handleSelectedKey("3", "/usuarios/novo")}
https://ant.design/components/menu/
EDIT
Based on research into your design library, your onclick and handle select must be at the top level of the menu component. Just copy the syntax that they use in their example code.
https://ant.design/components/menu/
I want to create an onBlur event on the left panel such that it automatically closes when the user clicks the panel to the right. I tried using the onMouseLeave event but the closing animation is not smooth. I also wanted if they could click a button on the right panel it closes the left panel at the same time execute the button function which rules off the use of a click away listener.
all this works with the on blur but the problem is how do I stop the event from firing when I click its child component
left panel code
const options = [
{
title: 'System Config',
icon: Settings,
list: [
{ name: 'General Settings', to: path },
{ name: 'Product Defaults', to: `${url}/pDefaults` },
{ name: 'Inventory Impects', to: `${url}/invImpects` },
],
},{
title: 'dashboard',
icon: Dashboard,
list: [{ name: 'Reports', to: `${url}/reports` }],
},
];
<Drawer onBlur={() => setOpen(false)}>
<Box>
<IconButton onClick={handleDrawer}>
{!open ? <ChevronRightIcon /> : <ChevronLeftIcon />}
</IconButton>
<Divider />
</Box>
<List>{options.map((opt, i) =>(
<ListItem button key={opt}>
<NavLink activeClassName={classes.activeTab} to={opt.to}>
<ListItemIcon className={classes.listItemIcon}>
<Icon />
</ListItemIcon>
<ListItemText className={classes.listItemText} primary={opt.title} />
</NavLink>
</ListItem>
))}
</List>
</Drawer>
right panel code
<Box className={classes.content}>
<Switch>
<Route exact path={path} component={GeneralSettings} />
<Route path={`${path}/pDefaults`} component={ProductDefaults} />
<Switch>
</Box>
There's ClickAwayListener component in MaterialUI, looks like it's what you need.
One option to solve this is to use a hook that detects when you click outside of an element. Here's an example of such hook. The ref should be assigned to the topmost React Element in your left panel
I am using ReactTransitionGroup with ReactRouter.
The goal is to reroute smoothly from one component to another. The problem - is that the component is rendered twice.
An example of a component (view) that renders twice
I am using the console to check. You might say that this is not critical. But, the problem is that because of this problem, 2 requests go to the server (one extra). Therefore, it is desirable for me to get rid of this bug.
This is the component itself - the switch
When switching a route, the console issues logs twice
I need to figure out why the side effect is being called twice. If there is not enough information, then write comments. I will try to answer as quickly as possible.
Here's an example from the documentation. I have achieved this effect, but the problem has already been described.
UPD: I remember very well that once it worked like a clockwork. But, probably, I myself did not notice that I changed something, which led to this problem.
UPD: If you need a code, then please, the required elements:
const TabList = ({ tabs }) => {
return (
<nav className="p-my-company__tabs">
{tabs.map(({ to, label, id }) => (
<NavLink to={to} key={id}>
<div>{label}</div>
</NavLink>
))}
</nav>
);
};
const TabViews = ({ tabViews }) => {
const location = useLocation();
return (
<div className="p-my-company__views">
<TransitionGroup>
<SwitchTransition mode="out-in">
<CSSTransition
key={location.pathname}
classNames={{
enter: 'move-enter',
enterActive: 'move-enter-active',
exit: 'move-exit',
}}
timeout={100}>
<Switch>
{tabViews.map(({ path, Component, id }) => (
<Route path={path} render={() => <Component />} key={id} />
))}
</Switch>
</CSSTransition>
</SwitchTransition>
</TransitionGroup>
</div>
);
};
<div className="p-my-company__panel">
<TabList
tabs={[
{ to: ROUTES.COMMON_INFO, label: 'Общая информация', id: 1 },
{ to: ROUTES.SHOWCASE, label: 'Моя витрина', id: 2 },
]}
/>
<TabViews
tabViews={[
{ path: ROUTES.COMMON_INFO, Component: CommonView, id: 1 },
{ path: ROUTES.SHOWCASE, Component: ShowCaseView, id: 2 },
]}
/>
</div>
const ShowCase = () => {
useEffect(() => {
console.log(2);
}, []);
return <div>ShowCase</div>;
};
Looks like the Switch component from React Router and React Transition Group don't work well together. The docs recommend avoiding the usage of the Switch component and passing a function to the Route's children prop. Since the function will be called regardless of whether there is a match or not, you can conditionally render Component if there's one.
<>
{tabViews.map(({ path, Component }) => (
<Route exact path={path} key={path}>
{({ match }) => (
<TransitionGroup>
<SwitchTransition mode="out-in">
<CSSTransition
in={match != null}
classNames={{
enter: 'move-enter',
enterActive: 'move-enter-active',
exit: 'move-exit',
}}
timeout={100}
unmountOnExit
key={location.pathname}
>
<div className="page">{match && <Component />}</div>
</CSSTransition>
</SwitchTransition>
</TransitionGroup>
)}
</Route>
))}
</>
I have dynamic menu items created from api. I'm calling class change function onClick but class is adding to all menus. I need add class to only clicked element not to whole menu list below is my code.
{menuSideBar.map(menu => (
<ListItem
className={SideMenuClass.join(" ")}
onClick={this.toggleClass.bind(this)}
button
>
<ListItemIcon className="sidebar_menu_icons">
<SendIcon />
</ListItemIcon>
<Link className="sidebar_menu_links" to={menu.url != "" ? "/" + menu.url : "#"}>
<ListItemText inset primary={menu.resourceValue} />
</Link>
</ListItem>
))}
Below is function
toggleClass = () => {
this.setState({ addClass: !this.state.addClass });
};
let SideMenuClass = ["sidebar_menu_list"];
if (this.state.addClass) {
SideMenuClass.push("selected_sidebar_menu");
}
Please help how can I add class to only clicked element?
Thank you.
You can save id's of selected items as array in state
{menuSideBar.map(menu => (
<Item
className={this.state.ids.includes(menu.id) ? 'active' : ''}
onClick={() => {
this.setState(oldState => ({
ids: oldState.ids.includes(menu.id) ? oldState.ids.filter(x => x !== menu.id) : [...oldState.ids, menu.id]
}));
}}
button
/>
))}
Example: https://codesandbox.io/s/4wv6n31q90?fontsize=14
Or if you need only last one selected:
{menuSideBar.map(menu => (
<Item
className={this.state.lastClicked === menu.id ? 'active' : ''}
onClick={() => {
this.setState({lastClicled: menu.id});
}}
button
/>
))}
Store menu item id in the state - then in render (map) check if equals to current element - adjust classes acordingly (apply class for selected only).
On my webapplication I use a json file to store my different routes, and I loop over an array inside this json file to create content, such navbar buttons.
The problem I face is that I would like to use a different icon for each value displayed from the json file, and I cannot store the icon component into the json file.
Here is my sample of code with the loop on the array contained in the json file
{props.buttons.button.map((button, index) => (
<div key={index}>
{(button.isAuth === props.isAuth || button.isAuth === 3) && (
<>
<Link to={button.to} className="link">
<ListItem button>
<ListItemIcon>
<InputIcon />
</ListItemIcon>
<ListItemText primary={button.label} />
</ListItem>
</Link>
</>
)}
</div>
))}
Here is a sample of the json file
{
"button": [
{
"label": "Home",
"isAuth": 3,
"to": "/"
},
{
"label": "About",
"isAuth": 3,
"to": "/about"
}
]
}
Currently, for each data on my json file, always the same icon component is displayed : <InputIcon />.
How can I display a different icon component for each data from the json file (such as <HomeIcon /> for the home button, <LogInIcon /> for the login one, ...) without using and if/else
Thanks
If possible you can structure the <InputIcon /> component to accept a prop and pass the label to this component.