SAP/ui5-webcomponents

Overflow Toolbar

Closed this issue · 5 comments

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
Are there any plans to add a component like the "classic" SAPUI5 OverflowToolbar? This would help us e.g. building an ObjectPageLayout on top of the ui5-webcomponents.

Describe the solution you'd like
A clear and concise description of what you want to happen.
I would like to have an Overflow Toolbar like in SAPUI5: https://sapui5.hana.ondemand.com/#/entity/sap.m.OverflowToolbar

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
none

Additional context
Add any other context or screenshots about the feature request here.

Still under consideration - whether to add it and if yes, to which package. To discuss with @petermuessig

Requested also by @lateefsofi with #2249

Hi @MarcusNotheis is planned for research and later for development.

The scope and features of the OverflowToolbar web component are under discussion. The web component won't match the sap.m.OverflowToolbar in terms of functionality, but the goal is to support the use-case of the actions overflow in the Dynamic Page Header.

Hi @dobrinyonkov once when you have clarity on the timelines you can update the milestone and move the item into planned/in-progress ect.

BR,
ilhan

Internal reference: BGSOFUIPIRIN-6088

Overflow Toolbar challenges

The problems:

  • Web components use slots (physical, not logical, browser-level mechanism) to render children. Therefore, a component's children can only be rendered by the component itself (<slot> in its own shadow root), or by another component in the shadow root (transitive <slot>). However, OTB would require a static area for the popup to avoid visual glitches, as all other similar components do. It is not possible to render the slotted items from the toolbar to the static area item of the toolbar, as these are completely independent parts of the DOM - we can't render a <slot> in the static area item for content that is in another part of the DOM (OTB itself).
  • OTB performs transformations/overstyling. For example, a segmented button is displayed as a select in the overflow menu. The app will attach an event listener to the segmented button, but if it overflows, the user will never click it, the user will instead click a select that is meant to represent the segmented button. Thus, the original event will never be fired. We would need to manually fire events on the segmented button. Important: we can do such mappings for semantic events (selection-change of the ui5-select -> change for the segmented button for example), but if the app listens to other events such as mouseover/mouseout, we can't know how and which ones to proxy.

Possible solutions:

  1. [My preferred] We do it like the MDK Overflow Toolbar - it has abstract items (ui5-otb-button, ui5-otb-select, ui5-otb-checkbox, etc...). Thus, we do not render the slotted items at all, but rather their representations both inside the toolbar, and in the static area. This is how all other similar components work (ui5-select, ui5-combobox, etc).
    Pros: we completely bypass the "slotting-to-static-area" problem; we control the transformations (segmented button -> select in the menu; design changes such as button transparency etc...) and we can enforce good design. As we use abstract items, users won't attach event listeners to the items, but the OTB itself will have one big "interact" event which will be agnostic of the position of the item that fired the event (toolbar or menu). Another benefit is that we don't expose the full APIs of the items that go in the toolbar, but rather whatever we decide to support.
    Cons: users can't pass whatever they like, but only whatever we allow with our limited list of abstract items. Additionally, when we add new properties to the button/select/etc... we'd sometimes have to add their counterparts to the OTB abstract items. This is both good and bad, as outlined above, as we can control which ones we want.

  2. We clone slotted content to the static area (as in the years-old prototype). We can't slot the content, but we can clone it and keep it synchronized.
    Pros: users can pass everything they want
    Cons: performance impact from synchronizing cloned content, event bubbling complications, limitations to the usage as HTML elements that you passed to the OTB won't be the same instances in the menu, but rather clones. This could cause logical issues in the app. Events, bound to buttons passed to the OTB, will actually bubble from within the static area. Overall - technically very complex. We'll run into complications if we decide to proxy events.

  3. We don't use a static area for OTB and document this as a limitation. We render the popup in the same template as the OTB itself.
    Pros: users can pass everything they want; and at the same time there will be no complications from cloning, mutation observers, event bubbling. The button in the OTB is the same button as in the menu, so the event will always bubble from the same DOM.
    Cons: the OTB will be prone to visual glitches such as "overflow:hidden" on itself, or one of its parents, cutting off parts of the menu; or issues with CSS transforms bugging the popup position. This would be inconsistent to all other components that show popups (as they all use the static area and thus avoid similar issues). Another issue will be that when there are transformations (f.e. segemented button -> select), people will bind event listeners to the segmented button and will get events from the select. We would still need to somehow proxy the events.

  4. We create a "semi-automatic" OTB - whenever a component is about to overflow, we fire an event, and it's up to the app to do the transformations, movement to the menu, etc... This way the app will keep track of what's going on, but there will be maybe too much glue code and a lot of the value of having OTB would be lost.