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

docs: add popover API blog post #8806

Merged
merged 6 commits into from
Apr 19, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 179 additions & 0 deletions packages/website/blog/releases/popover-api-in-v2.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
---
title: Popover API in UI5 Web Components 2.0
tags: [release, v2, popover API]
slug: /releases/popover-api-in-v2
---

UI5 Web Components 2.0 will provide greatly improved popups by taking advantage of the [native browser popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API).

## What is the popover API?

The [popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API) is a browser-native solution to displaying popup-like components (Popovers, Dialogs, etc.).
above all other content, regardless of its HTML structure and CSS applied.

## Popups in **version 1.x**

There used to be a so-called "static area" (`<ui5-static-area>`) - a DOM element directly in the `<body>` where the popups of all components were placed.
This guaranteed that even if the HTML document had `overflow: hidden`, `transform`, or similar CSS rules applied, or the component was in a *stacking context*, its popup would still be positioned correctly.

Example of `ui5-date-picker`'s DOM structure in **v1.24**:

```html
<body>
<ui5-static-area>
<ui5-static-area-item> <!-- A static area item, associated with the DatePicker component -->
#shadow-root
<ui5-responsive-popover></ui5-responsive-popover> <!-- here goes the Popover part of the DatePicker component -->
</ui5-static-area-item>
</ui5-static-area>

.........

<div style="transform: translate(12rem, 12rem)"> <!-- a parent node has CSS that normally breaks popup positioning -->
<ui5-date-picker>
#shadow-root
<ui5-input></ui5-input> <!-- The date Input part of the DatePicker component -->
</ui5-date-picker>
</div>
</body>
```

As you can see, the component used to be physically divided in two parts:
- The "main" part (the `ui5-date-picker` tag itself) containing the date selection input
- The "popover" part (the `ui5-static-area-item` tag, associated with the said date picker) containing the picker (calendar with years/months/days).

## Popups in **version 2.x**

There is no longer need for a "static area" since the browser now ensures the correct positioning of popups thanks to the popover API.

Example of `ui5-date-picker`'s DOM structure in **v2.0**:

```html
<body>
<div style="transform: translate(12rem, 12rem)"> <!-- a parent node has CSS that normally breaks popup positioning -->
<ui5-date-picker>
#shadow-root
<ui5-input></ui5-input> <!-- The date Input part of the DatePicker component -->
<ui5-responsive-popover popover="manual"></ui5-responsive-popover> <!-- the Popover part of the DatePicker component -->
</ui5-date-picker>
</div>
</body>
```

The component is no longer physically divided in two parts:
- Both the input and the popover are inside the `ui5-date-picker` itself
- The popover has the **popover="manual"** attribute (introduced with the popover API) that ensures it will be displayed above anything else on the HTML page.

It's that simple!

## The **practical** benefits

### Simpler and more robust components
- Easier to develop and maintain.
- Everything belonging to a component is now in one place! This includes code logic, HTML and CSS.

### Enhanced overstyling capabilities for apps
- We can now provide [CSS Shadow Parts](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_shadow_parts) also for the "popup part", not just in the "main part" of the component!
- [CSS Custom Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) set on the component will also have effect for its "popup part"!

Consider the following example:

```html
<body>
<style>
#mc::part(root) {
background: blue;
}
#mc::part(list) {
margin: 0.5rem;
}
</style>

<my-component id="mc">
#shadow-root
<div part="root"></div>
<ui5-popover>
<ui5-list part="list"></ui5-list>
</ui5-popover>
</my-component>
</body>
```

Since the popover is now part of the component, component authors can provide CSS Shadow Parts for elements in the popover, in addition to the existing CSS Shadow Parts.

### Components with popups can now have physical children

Web components with popups had a **hard limitation** of not being able to slot children to the popup.

Example of `ui5-select`'s (simplified) DOM structure in **v1.24**:

```html
<body>
<ui5-static-area>
<ui5-static-area-item> <!-- static area item of the ui5-select -->
#shadow-root
<ui5-responsive-popover> <!-- the "dropdown" part of the ui5-select -->
<ui5-list> <!-- the list inside ui5-select's dropdown -->
<ui5-li text="Option 1"></ui5-li> <!-- list item for the 1st ui5-option -->
<ui5-li text="Option 2"></ui5-li> <!-- list item for the 2nd ui5-option -->
<ui5-li text="Option 3"></ui5-li> <!-- list item for the 3rd ui5-option -->
</ui5-list>
</ui5-responsive-popover>
</ui5-static-area-item>
</ui5-static-area>

.........

<ui5-select>
#shadow-root
<div></div> <!-- The "box" part of the select -->

<ui5-option>Option 1</ui5-option>
<ui5-option>Option 2</ui5-option>
<ui5-option>Option 3</ui5-option>
</ui5-select>

</body>
```

As you can clearly see from the example, there is no way to **slot** the `ui5-option` components into the `ui5-list` as it is in a completely different part of the DOM, due to the need for a static area.
Instead, we can only provide **logical** `ui5-option` components and just use their **text content** for the `text` property of the list items (`ui5-li`) in the static area.

Example of `ui5-select`'s (simplified) DOM structure in **v2.0**:

```html
<body>
<ui5-select>
#shadow-root
<div></div> <!-- The "box" part of the select -->
<ui5-responsive-popover> <!-- the "dropdown" part of the ui5-select -->
<ui5-list> <!-- the list inside ui5-select's dropdown -->
<slot></slot>
</ui5-list>
</ui5-responsive-popover>

<ui5-option><strong>Option</strong> 1</ui5-option>
<ui5-option><ui5-icon name="accept"></ui5-icon> Option 2</ui5-option>
<ui5-option><i>Option 3</i></ui5-option>
</ui5-select>

</body>
```

Now that the popover is part of the `ui5-select` itself, it's possible to have **physical** `ui5-option`s and slot their content directly into the popover or its children (`ui5-list` in this example).

This allows us to provide support for **custom user content** for components that had strict predefined APIs in the past!

### Easier testing for both apps and component package authors
- Tests no longer need to know how to find the static area item, associated with a given component - everything is directly in the shadow root!
- Writing tests is much simplified.

### Cross-framework popup compatibility for the future
- Frameworks who use the native browser popover API no longer need to synchronize themselves (negotiate `z-index` values, etc.).
- The last popup to be opened will always be on top (guarnateed by the browser)!

## When can I start using it?
- The current versions of all supported browsers (Chrome, Safari, Edge, and now also Firefox as of version 125) fully support the popover API. [See Can I Use report](https://caniuse.com/?search=popover).
- By the time **v2.0** is officially released (we are at **v2.0-r.c.2** as of writing this blog post) we expect that each major browser will have already released at least 3 stable versions since the introduction of the popover API.

Make sure to check our blog for future announcements, including the official release date of **UI5 Web Components 2.0**!