Keep the selected options in the Sidebar when resizing the screen - javascript

My site has a sidebar (FiltersSideBar in my code) that contains filters. When the browser is expanded to full screen, the sidebar is in open mode on the left. If the screen width becomes less than 600, the sidebar is hidden and a button (ArrowBackIosNewIcon in my code) appears that can open the sidebar (as if overlaying the home page).
The problem with my code is that when the sidebar changes position (opens/closes), its state is not saved - all sidebar elements return to their original state. Although the applied filters continue to work.
That is, if the user selected any filters in the full-screen mode (for example, checked some categories), they were applied. But after that the browser window shrinks, the filters themselves remain applied, but the sidebar is displayed in the default mode (i.e. the checkboxes are empty again).
I would like to make it so that regardless of the size of the page the sidebar retains its appearance.
FiltersSideBar.jsx
export default function FiltersSideBar(props) {
return (
<CardContent className={props.className}>
<Table>
<TableBody>
<TableRow>
<TableCell>
<Filter1 />
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Filter2 />
</TableCell>
</TableRow>
</TableBody>
</Table>
</CardContent>
);
}

I don't see how you pass the filters to the sidebar.
But this issue happens because you completely destroy the sidebar to hide which resets its state to default, it would be better to just manipulate the style with display and transition without destroying the sidebar.
like here.
https://codesandbox.io/s/zealous-hodgkin-lf7qwt
Another solution is to make the filters state in the parent component of the sidebar and pass props to it.

Related

How to make react-window FixedSizeList scroll with the viewport instead of the component's scroll bar?

I am trying to integrate react-window's FixedSizeList and FixedSizeGrid components to increase the initial rendering speed of my page. Is there some way for me to let the user scroll down the react-window component using the viewport's scrolling area? I was also
wondering if there is some way to remove the scrollbar from the react-window component and only use the viewport's scrolling as I described above.
I tried integrating the documentation version of FixedSizeList into my page and as you can see, since the total height of all my rows is greater than the height I specified in the component so the vertical scrollbar beside the component appears, which I want to remove. I also cannot figure out how to let scrolling downwards on the viewport make the react-window component scroll down the rest of its rows.
From looking online, I think I might need to modify the CSS style of the FixedSizeList to have overflow:hidden to remove the scrollbar but how can I ensure that I keep the scrolling functionality and that the user can scroll down the component from anywhere in the viewport?
Current version with no react-window
FixedSizeList version
const Row = ({ index, style }) => (
<div style={style}>Row {index}</div>
);
<FixedSizeList
height={500}
itemCount={38}
itemSize={35}
width={"100%"}
>
{Row}
</FixedSizeList>
One solution is to use a package linked from the react-window github page called react-virtualized-auto-sizer. It is also made by bvaughn and is a good solution to the problem.
This solves the issue by allowing you to set the height of your FixedSizedList to the height of its content, so it does not get a scrollbar. Here's how that would look:
<AutoSizer>
{({ height, width }) => (
<FixedSizeList
className="List"
height={height}
itemCount={1000}
itemSize={35}
width={width}
>
{Row}
</FixedSizeList>
)}
</AutoSizer>
Here's a full example on codesandbox:

React MaterialUI <ListItemSecondaryAction> gets stuck when dragging inside react-beautiful-dnd Draggable?

I'm using react-beautiful-dnd to make some draggable list items using Material UI ListItems.
My ListItems have a ListItemText and a ListItemSecondaryAction which is a target (that wraps an icon) for opening a context menu.
const DraggableListItem = ({ leaf, index, path, handleClick }) => {
return (
<Draggable draggableId={String(leaf.id)} index={index}>
{(provided) => (
<ListItem
{...provided.draggableProps}
{...provided.dragHandleProps}
innerRef={provided.innerRef}
button component={NavLink}
to={path + '/' + leaf.id}
>
<ListItemText primary={leaf.content} />
<ListItemSecondaryAction>
<IconButton edge="end" aria-label="more options" value={JSON.stringify(leaf)} onClick={handleClick}>
<MoreHorizIcon />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
)}
</Draggable>
)
}
The problem I'm facing is that when dragging the Draggable, the context menu icon inside the ListItemSecondaryAction moves up a little bit and then freezes, despite the ListItemText being dragged around as expected.
Below you can see the item is being dragged to the top of the list and the other ListItemTexts are rearranging themselves around the placeholder/where the dragged item will be dropped. The context menu icon of the item being dragged however, is frozen a little above where it used to be, and the context menu icons for the other items haven't moved into new positions with them.
Simply replacing the ListItemSecondaryAction with a div fixes the issue, but I need the target provided by the ListItemSecondaryAction.
The below works as expected in terms of dragging the items: the IconButton is dragged inside the Draggable.
<div>
<IconButton>
<MoreHorizIcon />
</IconButton>
</div>
I have tried only rendering the ListItemSecondaryAction when not dragging (as opposed to a div when dragging) but there is still a delay in which the context menu of the item being dragged shows up stuck in one spot for a brief period of time. I can also just not render the context menu's target + icon at all when dragging but the same unsightly icon-stuck-in-a-weird-place-for-a-second issue happens.
How can I ensure that the IconButton is dragged with the Draggable when it's inside the ListItemSecondaryAction?
I fixed the icon issue using a variant of the solution here, but rather than rendering a separate ListItemIcon and still rendering the ListItemSecondaryAction, which changed the layout of each item, I found it works better to not render the ListItemSecondaryAction at all when dragging and simply render an Icon without any ListItemIcon or IconButton wrapper. The lone Icon is darker when rendered as a child of the ListItem though. After styling the icon on its own to match the color of the icon inside the secondary action, it looks good.
dragInProgress is a piece of state passed to all list items from the parent list so that they render just the icon when dragging. snapshot is from the snapshot passed by the function in the Draggable, as shown in the linked question. snapshot.isDragging is also checked to avoid the momentary jump of the dragged item's icon while the state dragInProgress is updating and causing the items to re-render.
<ListItem
{...provided.draggableProps}
{...provided.dragHandleProps}
ref={provided.innerRef}
>
<ListItemText primary={item.content} />
{dragInProgress || snapshot.isDragging ?
<MoreHorizIcon style={{color:'rgba(0, 0, 0, 0.54)'}} />
:
<ListItemSecondaryAction>
<IconButton>
<MoreHorizIcon />
</IconButton>
</ListItemSecondaryAction>
}
</ListItem>
Note:
Unfortunately the ListItemSecondaryAction rendered when not dragging doesn't play well with touch (tested on android on chrome) and must be dragged twice to start moving the items. I may put this more specific issue in a separate question.

Nextjs with material-ui; Component displayed twice when CardHeader action is set

I am displaying some material-ui Cards horizontally in a div from data loaded from the backend and rendered server side using NextJS, however when the action property is present in the CardHeader, the view is distorted.
The distortion is a little bit hard to explain so I have reproduced it minimally in CodeSandbox. After removing the action property, the items are rendered correctly, however you will need to reload the mini-browser to see the effect.
<CardActionArea>
<Card>
<CardHeader
avatar={<Avatar alt={value}>{value}</Avatar>}
/** If action is removed, the issue goes away */
action={
<IconButton>
<ThumbUpOutlinedIcon />
</IconButton>
}
title={value}
subheader={value}
/>
<CardContent>
<Typography variant="h6">{value}</Typography>
</CardContent>
</Card>
</CardActionArea>
As you can see above the main div containing the items is at the top with the items horizontally arranged, however there are additional items which are arranged vertically below the div.
My guess is that the top items correctly rendered were rendered in the client side and the bottom items vertically rendered (which also shouldn't be there) were obtained from the server because on inspection of the source, the bottom incorrectly rendered items were not within the __next element.
Why is the presence of the action property in the CardHeader causing this? Or is it possible that my setup with Next and material-ui is incorrect? Thanks.

Making antd's Sider responsive

I am attempting to implement a responsive app with antd.
One of the things I have is a Sider menu as my main navigation. One of the things I would like to do is that on small screens this sider be collapsed (as the hamburguer icon preferrably). I have no idea how to even start this. My component with the sidebar looks something like this:
class App extends React.Component {
render() {
return (
<Layout>
<Sider width={200} collapsedWidth={500}>
<Menu
mode="inline"
defaultSelectedKeys={['1']}
defaultOpenKeys={['sub1']}
style={{ height: '100%' }}
>
<Menu.Item key="1">option1</Menu.Item>
<Menu.Item key="2">option2</Menu.Item>
<Menu.Item key="3">option3</Menu.Item>
<Menu.Item key="4">option4</Menu.Item>
</Menu>
</Sider>
</Layout>
);
}
}
I should probably also point out that from the Layout docs, the following is said:
Note: You can get a responsive layout by setting breakpoint, the Sider will collapse to the width of collapsedWidth when window width is below the breakpoint. And a special trigger will appear if the collapsedWidth is set to 0.
However I could not get this to work. Perhaps I misunderstand it.
Unfortunately I am not able to embed my sample app in the editor here, so I here is my working sample app. All I would like to do is collapse my Sider navbar into a hamburguer icon or even an arrow like icon on small screens. Where do I go from here?
You have a collapsible sider official example.
From here you can choose whatever width \ icons you need based on state.
Also, you have a good example of antd components, especially a sidebar with the hamburger icon.

Side navigation scroll icons are not appearing even if the content height is more than screen height

I am using sap.tnt.SideNavigation in order to create side panel.For that i am creating a page and the page has sap.tnt.SideNavigation which consist of navigation items to display in side navigation.So the xml view is like this,
<Page>
<content>
<m:ToggleButton icon="sap-icon://menu2" press="onCollapseExapandPress"/>
<SideNavigation id="sideNavigation" visible="false">
<item>
<NavigationList itemSelect="onItemSelect" items="{path:'/widgetsToLoad/widgets'}">
<NavigationListItem icon="{icon}" visible="{inPanel}"
tooltip="{name}"></NavigationListItem>
</NavigationList>
</item>
</SideNavigation>
</content>
</Page>
After doing this eventhough the content height is nore than screen height it will not show scroll icons instead scroll bar will come.How to fix this?
According to the documentation sap.tnt.SideNavigation should be used only with sap.tnt.ToolPage as parent layout control. Thus it might not work perfectly within a Page control.
In general the scroll items are shown if the SideNavigation is not expanded, otherwise the scroll bar is shown. You can check this by playing around with the ToolPage example.

Categories