Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamically visible resizable panels aren't supported #282

Open
jezell opened this issue Feb 3, 2025 · 3 comments · May be fixed by #285
Open

Dynamically visible resizable panels aren't supported #282

jezell opened this issue Feb 3, 2025 · 3 comments · May be fixed by #285
Assignees
Labels
accepted A valid and reproducible issue bug Something isn't working

Comments

@jezell
Copy link
Contributor

jezell commented Feb 3, 2025

Steps to reproduce

Add a ShadResizablePanelGroup, add 2 panels to it. Conditionally toggle one of the panels so it gets removed from the widget tree. An exception will be thrown.

It's pretty common for panels themselves to have view toggles, but if you try to implement that with ShadResizablePanelGroup you can't really do it without using a hack like changing the key of the group every time the state changes.

Additionally, the computation logic is a bit weird as soon as this happens. Maybe it should work more like flexbox sizing because it's a bit of extra work to do the flex sizing yourself in the dynamic panels case. Imagine a case with 3 panels, hiding one of the panels should cause the other two to fill the remaining space with their proportions. With flex sizing this works as expected, but with setting absolute percentages you have to basically implement the flex sizing algorithm yourself to get it to work properly with ShadResizablePanel

Side note, if default is outside the range of min / max, rather than throwing it should probably just take clamp the value.

Expected results

No exception is thrown

Actual results

Exception is thrown when toggling panels on and off

shadcn_ui version

0.18.5

Platform

MacOS, Web

Code sample

Code sample
ShadResizablePanelGroup(
  showHandle:
      true,
  dividerSize:
      1,
  dividerThickness:
      1,
  children: [
    if(showFilePane)
    ShadResizablePanel(defaultSize: defaultFilesPaneSize, minSize: .1, child:  FilesPane()),
    if(showPreviewPane)
    ShadResizablePanel(defaultSize: defaultPreviewPaneSize, minSize: .5, child: DocumentsPane()),
    if(showChatPane)
    ShadResizablePanel(defaultSize: defaultChatPaneSize, minSize: .1, child:  MessagingPane()),
  ])),

Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
[Paste your output here]
@jezell jezell added bug Something isn't working triage Issues that need assessment and prioritization labels Feb 3, 2025
@nank1ro
Copy link
Owner

nank1ro commented Feb 4, 2025

Your use case is to completely hide it or just change its size to 0 programmatically? I want to know this because I need to know if you need the divider to still be visible or not.

Can you clarify why do you need the default size to be clamped? I'm worried about adding this logic because I think it can make the logic pretty complex, each default size is handled in a different class, the fact the sum is always 1 is what makes the logic working.

@nank1ro nank1ro linked a pull request Feb 5, 2025 that will close this issue
@nank1ro
Copy link
Owner

nank1ro commented Feb 5, 2025

I made a PR to improve the controller handling and to simplify the resize logic.

resizable.mov
class ResizablePage extends StatefulWidget {
  const ResizablePage({super.key});

  @override
  State<ResizablePage> createState() => _ResizablePageState();
}

class _ResizablePageState extends State<ResizablePage> {
  final controller = ShadResizableController();
  double storedSize = 0;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    return Column(
      children: [
        ShadButton(
          onPressed: () {
            if (controller.panelsInfo.first.size <= 0.05) {
              controller.resize(index: 0, size: storedSize);
            } else {
              storedSize = controller.panelsInfo.first.size;
              controller.resize(
                index: 0,
                size: 0,
              );
            }
          },
          child: const Text('Toggle First Panel'),
        ),
        SizedBox(
          width: 300,
          height: 200,
          child: DecoratedBox(
            decoration: BoxDecoration(
              borderRadius: theme.radius,
              border: Border.all(
                color: theme.colorScheme.border,
              ),
            ),
            child: ClipRRect(
              borderRadius: theme.radius,
              child: ShadResizablePanelGroup(
                controller: controller,
                mainAxisSize: MainAxisSize.min,
                showHandle: true,
                children: [
                  ShadResizablePanel(
                    defaultSize: .2,
                    // minSize: 0,
                    maxSize: 0.8,
                    child: Center(
                      child: Text('One', style: theme.textTheme.large),
                    ),
                  ),
                  ShadResizablePanel(
                    defaultSize: .4,
                    // minSize: 0.1,
                    maxSize: 1,
                    child: Center(
                      child: Text('Two', style: theme.textTheme.large),
                    ),
                  ),
                  ShadResizablePanel(
                    defaultSize: .4,
                    minSize: 0.1,
                    maxSize: 1,
                    child: Center(
                      child: Text('Three', style: theme.textTheme.large),
                    ),
                  ),
                ],
              ),
            ),
          ),
        )
      ],
    );
  }
}

Let me know what you would like to see improved!

@nank1ro
Copy link
Owner

nank1ro commented Feb 5, 2025

For example, do you want a flag to proportionally assign a size to each panel still visible when one of them goes to 0?
Because now only the second panel is resized and takes all the space leaved by the first panel.

@nank1ro nank1ro added accepted A valid and reproducible issue and removed triage Issues that need assessment and prioritization labels Feb 5, 2025
@nank1ro nank1ro self-assigned this Feb 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted A valid and reproducible issue bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants