mui / toolpad

Toolpad: Full stack components and low-code builder for dashboards and internal apps.
https://mui.com/toolpad/
MIT License
1.28k stars 283 forks source link

Add props to control sidebar's collapsed state in DashboardLayout component #4406

Open Mohammad-210 opened 4 days ago

Mohammad-210 commented 4 days ago

Summary

This feature request is to enhance the DashboardLayout component by adding two new props:

collapsed: A boolean prop that controls the initial state of the sidebar (collapsed or expanded). onToggleSidebar: A function prop that allows toggling the sidebar’s collapsed state from outside the DashboardLayout component. This setup will make the sidebar’s state externally controllable, enabling more dynamic and flexible UI behaviors in various responsive scenarios.

Examples

import React, { useState } from 'react'; import DashboardLayout from './DashboardLayout';

const AppProvider = () => { const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false);

const handleToggleSidebar = (collapsed) => { setIsSidebarCollapsed(collapsed); };

return ( <DashboardLayout collapsed={isSidebarCollapsed} onToggleSidebar={handleToggleSidebar}

{/ Application Content /} ); };

export default AppProvider;

Motivation

This feature will improve DashboardLayout’s flexibility and control by allowing parent components to manage and toggle the sidebar’s collapsed state. With responsive design requirements, many apps need to control the sidebar's visibility dynamically based on user interactions or screen size. This enhancement will make DashboardLayout more adaptable for complex UI requirements and enhance user experience across devices. The issue i face is i need a state to ensure the sidebar is collapsed or not to manage the responsiveness of design of rendered children comp

Search keywords: sidebar toggle, sidebar collapsed state, DashboardLayout, Material-UI, Toolpad sidebar, responsive sidebar, toggle sidebar from parent, sidebar props

bharatkashyap commented 4 days ago

Agree with providing a way to access the state of the sidebar, and also imperatively setting it. An alternative way of doing this is through a useSidebar hook:

const { collapsed, setCollapsed } = useSidebar();

const onClick = () => { if(!collapsed) { setCollapsed(); } 

This will enable components across the app to be able to access (and imperatively set) the sidebar's state instead of having to share props.

vikasgurjar commented 3 days ago

@Mohammad-210 are you planning to work on this and create a PR? If not, I can help with the PR

Janpot commented 3 days ago

a controlled prop makes sense to me. a hook will be constraint to descendants only, which is probably too limiting.

Mohammad-210 commented 3 days ago

@vikasgurjar I'm swamped with other tasks, I won't get to it.But I'm planning to fix it, but I haven't started yet. Feel free to create the PR!. if help needed let me know ..!

vikasgurjar commented 2 days ago

@Janpot from what I understand, controlled prop will have to be passed down to every child that needs it. Also even in that case these props will be constraint to descendants only

vikasgurjar commented 2 days ago

@bharatkashyap I'm thinking of using useNavigation instead of useSidebar for consistency as we already have a prop called 'hideNavigation'

const { collapsed, setCollapsed } = hideNavigation();

const onClick = () => { if(!collapsed) { setCollapsed(); } 
bharatkashyap commented 2 days ago

@bharatkashyap I'm thinking of using useNavigation instead of useSidebar for consistency as we already have a prop called 'hideNavigation'

const { collapsed, setCollapsed } = hideNavigation();

const onClick = () => { if(!collapsed) { setCollapsed(); } 

I discussed this with @mnajdova and we came to the conclusion that a controlled prop makes sense to begin with, while a hook/context can be implemented by users themselves if they need it as long as the prop is present. We could make an issue to collect upvotes on the hook feature request, to see if there is enough interest in providing that out of the box.

Let's focus on adding a controlled prop as part of this issue 👍🏻