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

menu component: option to collapse submenu when another submenu is opened (accordeon) #520

Closed
EvaBS opened this issue Sep 6, 2021 · 4 comments · Fixed by #522
Closed
Labels
discussion Extra attention is needed

Comments

@EvaBS
Copy link
Collaborator

EvaBS commented Sep 6, 2021

We're using the new menu component with the appFrame and have a lot of links in the navigation area. Showing more than one expanded submenu takes up too much space.

We would like the option to collapse an expanded submenu when another submenu is expanded, allowing only one single submenu to show its subitems at a time. Currently we cannot customize the menu component with this function ourselves because the expand/collapse handlers of submenu are not available.

Additional information: We want to navigate to an overview page AND expand the entries after the user clicks on the collapsed submenu.

Mockup

@ghost ghost added component/styling discussion Extra attention is needed labels Sep 6, 2021
@ghost
Copy link

ghost commented Sep 6, 2021

Currently there is no "global" state that would enable the whole menu component itself to manage the opening and closing of its submenus.

I could imagine that it would be possible to pass optional (sub-)stores into the submenu component, that could be watched by some "accordeon" store, so that each change of one property to true would disable all other properties ( = false). This way the open action of an arbitrary submenu would close the currently opened other submenu.

Afaik we do not have any "middleware" built-in that allows to watch state changes before they are applied by a store as new value, so we must take care of such an xor functionality when building a lens. The following example shows the approach in general (of course the data model could be improved as also the lens generation):

val menuStore = storeOf(listOf(true, false))

val contact = buildLens<List<Boolean>, Boolean>(
    "contact",
    { it[0] },
    { m, new -> m.withIndex().map { (i, _) -> if (i == 0) new else false } }
    //                                           ^^^^^^^^^^^^^^^^^^^^^^^
    //                                           keep only the current value (true or false)
    //                                           reset all others to false
)
val user = buildLens<List<Boolean>, Boolean>(
    "user",
    { it[1] },
    { m, new -> m.withIndex().map { (i, _) -> if (i == 1) new else false } }
)

// only one switch will beactive at most!
switch(value = menuStore.sub(contact)) { label(contact.id) }
switch(value = menuStore.sub(user)) { label(user.id) }

// TODO: accept external store within `SubMenuComponent` and `MenuContext.submenu` factory method.
menu {
    entry {
        // ...
    }
    submenu(value = menuStore.sub(contact)) {
        // ...
    }
}

I think this approach would enable the desired behaviour. The downside is, that there is no "ready to go" solution, as the crafting of the appropriate store always depends on the data structure avialable within the specific code.

An opposite approach would be to hide the management mostly within the MenuComponent and only provide some "accordeon(true)" property in order to activate this. Then the component would need to take care of creating the sub-stores, which would be a bit cumbersome, because of the declarative approach! (The submenu simply does not know about any index or alike if it gets composed. So there would be the need for some after initialization action...)

@EvaBS
Copy link
Collaborator Author

EvaBS commented Sep 7, 2021

For now, I think that exposing the expand/collapse handlers for the submenus would be sufficient to implement our own solution. Of course my favorite usability option would be the accordeon(true) variant :-)
I talked to Jan about it and he seemed to have something on mind.

@ghost
Copy link

ghost commented Sep 7, 2021

What I have forgotten yesterday: Our submenu approach allows arbitrary nesting of submenus, so it will get even harder to keep track of this internally. But if someone has an idea, great! :-)

@jamowei
Copy link
Collaborator

jamowei commented Sep 7, 2021

@EvaBS can you please test and verify the solution from PR #522. Thanks!

@EvaBS EvaBS closed this as completed in #522 Sep 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants