Maintaining collapse state when drawer opens and closes - reactjs

I'm currently having troubles with the material-ui drawer (https://material-ui-next.com/ one)
When I open the mini variant, the collapse inside my menu resets (closes because of the "remount").
However I would like them to persist their current state (open/closed).
Does Anyone know a way to achieve this?
The drawer:
<Drawer type="permanent"
classes={{paper: classNames(classes.drawerPaper, !this.state.open && classes.drawerPaperClose)}}
open={this.state.open}>
<div className={classNames(classes.drawerInner)}>
<Navigation updateTitle={this.updateTitle}/>
</div>
</Drawer>
The navigation component: https://pastebin.com/webdmLXp
Rendered with open collapse:
After clicking the burger button:

Sure Mr who I share my lastname with, you need to keep state of each <MenuItem>. Just add an onClick to each menuItem and toggle the state in your component. This does not really relate to Material-ui, but is more a general React question.

Related

Dynamic Modal routing with NextJS like Instagram

I am looking for someone to help me with the following issue:
I am trying to implement a modal system where the modals are dependent on the route using NextJS.
So say I am on the following page:
website.com/help
and say I have the modals category1, category2, and category3, all of which I would prefer to be able to persist after closing them (they are loading iframes), however this is not a must.
Then I would want the routes for these modals to be:
website.com/help/category1
website.com/help/category2
website.com/help/category3
I have already found this in the official NextJS examples:
with-route-as-modal
But the problem I am having is that with queryString routing, when you reload/visit the modal route directly, the modal wont be used. So the content will become full screen (it is a page of its own).
With dynamic routing, this is not an issue, since if you visit the modal route directly the modal will be kept. But the problem I am having with this is that these modals aren't exactly modals, the original page "behind" the modal just becomes the body background. The other issue is that I wont be able to persist these.
Here is the demo on stackblitz:
https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-route-as-modal?file=README.md
I would appreciate anyone helping me with this so much because it has really driven me mad trying to solve this!
I have a solution that you may like. For the example you provided you only need to import <Grid/> in /article/[articleId].js like it's done in /index.js
so when you open the modal the articles/posts list is shown in the background
// article/[articleId].js
import Grid from '../../components/Grid';
<>
<Modal
isOpen={true}
onRequestClose={() => router.push('/', undefined, { scroll: false })}
contentLabel="Post modal"
>
<Article id={articleId} pathname={router.pathname} />
</Modal>
<Grid />
</>
don't forget to give scroll false in router.push() and <Link/> so when you go back to articles/posts list it doesn't jump to the top of the page
router.push('/', undefined, { scroll: false })
<Link
key={index}
href="/article/[articleId]"
as={`/article/${id}`}
scroll={false}
>
<a className={styles.postCard}>{id}</a>
</Link>
you can see an example here: https://stackblitz.com/edit/github-rkrovd

React TypeScript with Material UI

I would like to ask for help. How can I be able to render these menus under their correct and proper category menu? Currently, they would just pile against each other instead of rendering from their proper menu. I am using React together with TypeScript and I have been working for this nonstop and haven't found an answer. Hope someone could help.
This is a sample photo of the problem. They're all overlapping and rendering together instead of rendering it differently from the other menu.
This Message Menu would only render a Menu List drop down menu.
This Operation Menu would and should only render Ack, Unack, Clear, and Comment
Here's my source code.
const handleClick = (index: null, event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};
<Menu
id="basic-menu"
anchorEl={anchorEl}
open={open}
onClose={handleClose}
MenuListProps={{
"aria-labelledby": "basic-button",
}}
>
{customtoolinfo.menu_sub.map((custommenusubtool: any) => (
<MenuItem onClick={handleClose}>
{custommenusubtool.menu_sub_name}
</MenuItem>
))}
</Menu>
The issue is because you have same anchorEl value of all sub menus. This issue can be fixed in many ways. One way is to have only one menu and render it's sub-menus based on condition or second way is to have different anchorEl state for every submenu and control them based on menu

Why does material UI react stepper doesn't have tab focus?

The material-UI react stepper control steps do not receive the tab focus. Is there a way to enable tabFocus on the steps?
https://material-ui.com/components/steppers/
Already I see tabFocus is exist on the steps but the styles are not show. I think if you add focusRipple props attribute
<StepButton focusRipple onClick={handleStep(index)} completed={isStepComplete(index)} {...buttonProps}>
{label}
</StepButton>
true on the StepButton component you might be able to see the tab focus
https://codesandbox.io/s/material-demo-4m4si

Swipeable drawer in Material UI

I got a problem with Swipeable drawer from Material UI. In normal Drawer isnt nessesary to add function onOpen. SO my question is what should I add thare?
container={container}
variant="temporary"
open={mobileOpen}
anchor="left"
onClose={handleDrawerToggle}
onOpen={}
The "onOpen" is used for "opening" the drawer (its the behavior it will have when it opens) If you want a persistent drawer (always open) there are other options there!
adding: Within the onOpen you should handle the change of value so react knows it is open and material ui make the transition.
https://material-ui.com/components/drawers/#permanent-drawer
Good luck!

Semantic UI React side bar render pusher only on visibility change (redux/rematch)

I am using react and semantic. I am using the multiple sidebar example. The idea is that the left hand sidebar offers up some menu options, and then the right hand sidebar is the sub menu based on which option from the left menu is chosen. When a sub menu item is selected, a component is added to the Sidebar.Pusher, i.e displayed on the page.
It all works except re-rendering the content of the Sidebar.Pusher. This apparently only updates when the left hand side bar's visibility changes. I am using redux/rematch to handle state, and can see that the state that holds the content of the Sidebar.Pusher is being updated, but `render() is only being called when visibility changes of the sidebar.
The content of Sidebar.Pusher is an array, and I even tried displaying on the page the length of the array, which is being updated (pushed into) each time an item on the right hand sidebar is clicked. However this doesn't cause a render() to be fired, its literally when the left hand sidebar visibility changes.
Just to note, I did see this issue, however its from last year, and the answer wasn't enough for me to be able to fix the issue. Help would be appreciated.
Structure:
Index.js renders App.js, App.js renders Menu.js (which is a semantic set of tabs). One of the menu options is Sidebar.js which renders:
<Sidebar.Pushable as={Segment}>
<Sidebar
as={Menu}
animation="overlay"
direction="right"
inverted
vertical
visible={secondaryVisibility}
width="wide"
>
{focusedList.map((el, i) => {
return (
<Menu.Item key={i} as="a" onClick={() => this.addSegment(el)}>
<Article el={el} />
</Menu.Item>
)
})}
</Sidebar>
<Sidebar
as={Menu}
animation="overlay"
icon="labeled"
inverted
// onHide={this.handleSidebarHide}
vertical
visible={primaryVisibility}
width="wide"
>
<Menu.Item
onClick={() => this.changeTab(menuItem)}
as="a"
name="menuItem"
header
>
Menu Item
</Menu.Item>
</Sidebar>
<Sidebar.Pusher style={{ minHeight: "600px" }}>
<Segment basic>
{segments.map((el, i) => {
console.log(`el ${el}`)
return <Content key={i} segment={el} />
})}
</Segment>
</Sidebar.Pusher>
and all state (secondaryVisibility etc) is stored in rematch
Thanks
I haven't been able to identify the problem based on the code you've posted, could you provide more info such as the entire Sidebar.js and maybe what's in the Content component?. My guess would be that there's a HOC or lifecycle method getting in the way.
I've created a trivial example that seems to work fine, if I understand what you're trying to accomplish: https://codesandbox.io/s/myl6xpz9py
I got it. I forgot about immutability in state. Perhaps someone will benefit from this.
I was trying to update a state array with
let tmp = prevState.contract.segments
tmp.push(segment)
this.update({ segments: tmp })
However, this won't work as tmp is a reference to prevState.contract.segments, so this won't work, as pushing to tmp is equivelent to pushing to prevState.contract.segments.
you have to have a completely new array:
const tmp = [...prevState.contract.segments, segment]
this.update({ segments: tmp })
Now it works.

Resources