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

Improve Disclosure Component for State Creating Content #754

Open
ghost opened this issue Feb 27, 2023 · 2 comments · May be fixed by #862
Open

Improve Disclosure Component for State Creating Content #754

ghost opened this issue Feb 27, 2023 · 2 comments · May be fixed by #862
Assignees
Labels
discussion Extra attention is needed headless All about headless components and foundations
Milestone

Comments

@ghost
Copy link

ghost commented Feb 27, 2023

Status Quo

Currently the Disclosure component internally works in a way, that the panel is only rendered, if the state is open. As consequence the panel's content is only rendered (== evaluated), if the disclosure becomes opened.

Problem

Imagine some kind of "filter" component, that hides the filter UI inside the disclosure panel and only shows its current filtering state on the button. The filter DSL could be implemented as DSL very fritz2 alike:

data class MyFilterModel(val pattern: String?, val severity: Severity?) 
val somefilterStore = storeOf(MyFilterModel())

disclosure {
    filterGroup<MyFilterModel>(someFilterStore) {
        disclosureButton {
            // there are no filters, until the panel gets rendered, so there are no badges with the currently
            // actrive filter items.
            filters.renderEach { filter ->
                badge {
                    +filter.toString()
                }
            }
        }
        // This whole structure only gets rendered, if the state is "open"
        // -> the filterGroup won't have any content, until the panel is rendered!
        disclosurePanel {
            // now we define the separate "filters" and their UI representation with some custom function
            // `filter` that internally adds such a filter to the internal group.
            filter(MyFilterModel.pattern()) { storedPattern ->
                // declare the corresponding UI directly inside:
                input { ... }
            }
            filter(MyFilterModel.severity()) { storedSeverity ->
                input {
                    type(radio)
                    ...
                }
            }
        }
    }
}

As you can see the filterGroup heavily depends on the declaration of the individual filters. As those are located inside the panel, enclosing their corresponding UI representation, they were not evaluated until the disclosure gets rendered first.

Proposal

There is one basic solution, which then could be implemented in two different ways:
We could change the disclosure in a way, that it is always rendered, but stays "hidden" until it is opened, like we do with all the PopUpPanel based components like PopOver or ListBox.

  • we could therefore change the behavior of disclosure to work like this per default and only way.
  • we could offer the latter as kind of "RenderStrategy", so one can choose, which behavior fits better: The current existing one or the new one, which only hides its contents on close-state.

We must decide, whether the first solution has any unwanted impacts. I definitely would prefer a solution without enforcing the user to make a choice. But I am totally unsure, whether the current implementation can be droped out or not.

@ghost ghost added the headless All about headless components and foundations label Feb 27, 2023
@ghost ghost self-assigned this Feb 27, 2023
@ghost ghost changed the title Improve Disclosure Component for reactive Content Improve Disclosure Component for State Creating Content Feb 27, 2023
@jwstegemann
Copy link
Owner

To satisfy the specific use case you mentioned, we could also just call the render code once, when the disclosure is created without adding the created nodes to the dom...

@Lysander Lysander added the discussion Extra attention is needed label Dec 8, 2023
@henryB99
Copy link
Collaborator

We can't add flow-based animations to the disclosurePanel. We can only use lifecycle-based animations because the job handling the animation gets cancelled when the panel is unmounted. But using lifecycle-based animations can cause delays in page transitions for example, because fritz2 waits for the animation to finish before navigating (this is only a problem when navigating with the builtin fritz2 router, not the browser).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Extra attention is needed headless All about headless components and foundations
Projects
None yet
4 participants