diff --git a/packages/modules/data-widgets/src/themesource/datawidgets/web/_datagrid.scss b/packages/modules/data-widgets/src/themesource/datawidgets/web/_datagrid.scss
index bbc77135b4..d817a34753 100644
--- a/packages/modules/data-widgets/src/themesource/datawidgets/web/_datagrid.scss
+++ b/packages/modules/data-widgets/src/themesource/datawidgets/web/_datagrid.scss
@@ -346,8 +346,13 @@ $root: ".widget-datagrid";
position: relative;
&-grid {
+ &-head,
+ &-body {
+ display: contents;
+ }
&.table {
display: grid !important;
+ grid-template-columns: var(--widgets-grid-template-columns);
min-width: fit-content;
margin-bottom: 0;
&.infinite-loading {
@@ -487,106 +492,53 @@ $root: ".widget-datagrid";
}
.infinite-loading {
- .widget-datagrid-grid-head {
- // lock header width
- // and prevent it from having own scrolling
- // as scrolling is synchronized in JS
- width: calc(var(--widgets-grid-width) - var(--widgets-grid-scrollbar-size));
- overflow-x: hidden;
- }
+ // infinite loading grid limits height to initiate scrolling
+ max-height: var(--widgets-grid-table-height);
+ overflow: auto;
.widget-datagrid-grid-head {
- &[data-scrolled-x="true"],
- &[data-scrolled-y="true"] {
- z-index: 1;
+ .th {
+ // make header sticky when grid is scrolled.
+ position: sticky;
+ top: 0;
+ z-index: 10;
+ &:has([data-overlay-content]) {
+ // when there is popup open inside of the header cell, it should
+ // overlay other header elements, including ones from other grids.
+ z-index: 20;
+ }
}
}
- .widget-datagrid-grid-head[data-scrolled-y="true"] {
+ &[data-scrolled-y] .widget-datagrid-grid-head .th:after {
// add shadow under the header
// implying that grid is scrolled vertically (there are rows hidden under header)
- // the data attribute added in JS
- box-shadow: 0 5px 5px -5px gray;
- }
-
- .widget-datagrid-grid-body {
- // lock the size of the body
- // and enable it to have own scrolling
- // body is the leading element
- // header scroll will be synced to match it
- width: var(--widgets-grid-width);
- overflow-y: auto;
- max-height: var(--widgets-grid-body-height);
- }
-
- .widget-datagrid-grid-head[data-scrolled-x="true"]:after {
- // add inner shadow to the left side of the grid
- // implying that the grid is scrolled horizontally (there are rows hidden on the left)
- // the data attribute added in JS
content: "";
position: absolute;
+ bottom: -5px;
left: 0;
- width: 10px;
- box-shadow: inset 5px 0 5px -5px gray;
- top: 0;
- bottom: 0;
+ right: 0;
+ height: 5px;
+ background: linear-gradient(to bottom, rgba(0, 0, 0, 0.1), transparent);
}
}
-// styles for browsers that don't support subgrid
-// if the browser doesn't support subgrid
-// fall back header an body the contents and apply grid template to the table
-.widget-datagrid-grid.table {
- grid-template-columns: var(--widgets-grid-template-columns);
-}
-.widget-datagrid-grid-body,
-.widget-datagrid-grid-head {
- display: contents;
-}
-
-// styles for modern browsers
-@supports (grid-template-rows: subgrid) {
- .widget-datagrid-grid.table:not([data-has-scroll-x="true"]) {
- grid-template-columns: var(--widgets-grid-template-columns);
- .widget-datagrid-grid-body,
- .widget-datagrid-grid-head {
- display: grid;
- min-width: 0;
-
- // this property makes sure we align our own grid columns
- // to the columns defined in the global grid
- grid-template-columns: subgrid;
-
- // ensure that we cover all columns of original top level grid
- // so our own columns get aligned with the parent
- grid-column: 1 / -1;
- }
- }
-
- .widget-datagrid-grid.table[data-has-scroll-x="true"] {
- // reset the columns defined on table level
- // header and body will define their own instead
- // this is needed to make body horizontally scrollable
- grid-template-columns: initial;
- .widget-datagrid-grid-head {
- display: grid;
- min-width: 0;
-
- grid-template-columns: var(--widgets-grid-template-columns-head, var(--widgets-grid-template-columns));
- }
-
- .widget-datagrid-grid-body {
- display: grid;
-
- grid-template-columns: var(--widgets-grid-template-columns);
- }
+// add shadows at the left to imply that grid is scrolled horizontally
+.widget-datagrid-content:has(.widget-datagrid-grid[data-scrolled-x]) {
+ position: relative; // needed to keep :after element positioned inside
+ &:after {
+ content: "";
+ position: absolute;
+ left: 0;
+ z-index: 10;
+ bottom: 0;
+ top: 0;
+ width: 5px;
+ background: linear-gradient(to right, rgba(0, 0, 0, 0.1), transparent);
+ pointer-events: none;
}
}
-.grid-mock-header {
- display: contents;
-}
-
:where(#{$root}-paging-bottom, #{$root}-paging-top) {
display: flex;
flex-flow: row nowrap;
@@ -681,3 +633,7 @@ $root: ".widget-datagrid";
}
}
}
+
+[data-overlay-content] {
+ z-index: 15;
+}
diff --git a/packages/pluggableWidgets/combobox-web/src/components/ComboboxMenuWrapper.tsx b/packages/pluggableWidgets/combobox-web/src/components/ComboboxMenuWrapper.tsx
index cda1155f9a..51f414c827 100644
--- a/packages/pluggableWidgets/combobox-web/src/components/ComboboxMenuWrapper.tsx
+++ b/packages/pluggableWidgets/combobox-web/src/components/ComboboxMenuWrapper.tsx
@@ -61,6 +61,7 @@ export function ComboboxMenuWrapper(props: ComboboxMenuWrapperProps): ReactEleme
}
: style
}
+ data-overlay-content={isOpen || undefined}
>
{menuHeaderContent && (
(props.expanded ? {children}
: null)}
allowSameDay={false}
ariaLabelledBy={`${props.id}-label`}
autoFocus={false}
diff --git a/packages/pluggableWidgets/datagrid-web/src/components/ColumnSelector.tsx b/packages/pluggableWidgets/datagrid-web/src/components/ColumnSelector.tsx
index caac97e39c..9ec931e44b 100644
--- a/packages/pluggableWidgets/datagrid-web/src/components/ColumnSelector.tsx
+++ b/packages/pluggableWidgets/datagrid-web/src/components/ColumnSelector.tsx
@@ -125,6 +125,7 @@ export function ColumnSelector(props: ColumnSelectorProps): ReactElement {
id={`${props.id}-column-selectors`}
className={`column-selectors`}
data-focusindex={0}
+ data-overlay-content
role="menu"
style={{ ...correctedFloatingStyles, maxHeight }}
{...getFloatingProps()}
diff --git a/packages/pluggableWidgets/datagrid-web/src/components/Grid.tsx b/packages/pluggableWidgets/datagrid-web/src/components/Grid.tsx
index 9c3135bc33..b95527665d 100644
--- a/packages/pluggableWidgets/datagrid-web/src/components/Grid.tsx
+++ b/packages/pluggableWidgets/datagrid-web/src/components/Grid.tsx
@@ -2,10 +2,12 @@ import classNames from "classnames";
import { observer } from "mobx-react-lite";
import { PropsWithChildren, ReactElement } from "react";
import { useDatagridConfig, useGridSizeStore, useGridStyle } from "../model/hooks/injection-hooks";
+import { useInfiniteControl } from "../model/hooks/useInfiniteControl";
export const Grid = observer(function Grid(props: PropsWithChildren): ReactElement {
const config = useDatagridConfig();
const gridSizeStore = useGridSizeStore();
+ const [handleScroll] = useInfiniteControl();
const style = useGridStyle().get();
return (
@@ -17,6 +19,7 @@ export const Grid = observer(function Grid(props: PropsWithChildren): ReactEleme
role="grid"
style={style}
ref={gridSizeStore.gridContainerRef}
+ onScroll={handleScroll}
>
{props.children}
diff --git a/packages/pluggableWidgets/datagrid-web/src/components/GridBody.tsx b/packages/pluggableWidgets/datagrid-web/src/components/GridBody.tsx
index 6c27f43ca2..e4280c7a3a 100644
--- a/packages/pluggableWidgets/datagrid-web/src/components/GridBody.tsx
+++ b/packages/pluggableWidgets/datagrid-web/src/components/GridBody.tsx
@@ -8,22 +8,15 @@ import {
usePaginationVM,
useVisibleColumnsCount
} from "../model/hooks/injection-hooks";
-import { useBodyScroll } from "../model/hooks/useBodyScroll";
import { RowSkeletonLoader } from "./loader/RowSkeletonLoader";
import { SpinnerLoader } from "./loader/SpinnerLoader";
export const GridBody = observer(function GridBody(props: PropsWithChildren): ReactElement {
const { children } = props;
const gridSizeStore = useGridSizeStore();
- const { handleScroll } = useBodyScroll();
return (
-
+
{children}
);
diff --git a/packages/pluggableWidgets/datagrid-web/src/components/Header.tsx b/packages/pluggableWidgets/datagrid-web/src/components/Header.tsx
index 1c396b3b75..e2265daa1a 100644
--- a/packages/pluggableWidgets/datagrid-web/src/components/Header.tsx
+++ b/packages/pluggableWidgets/datagrid-web/src/components/Header.tsx
@@ -64,6 +64,7 @@ export function Header(props: HeaderProps): ReactElement {
onDrop={draggableProps.onDrop}
onDragEnter={draggableProps.onDragEnter}
onDragOver={draggableProps.onDragOver}
+ ref={ref => column.setHeaderElementRef(ref)}
>
(
- entries => {
- const container = entries[0].target.parentElement!;
-
- const gridContainer = container.closest
(".table");
- const gridBody = container.closest(".table-content");
- if (gridContainer && gridBody) {
- if (gridContainer.dataset.hasScrollX === "true") {
- if (gridBody.scrollWidth <= gridBody.clientWidth) {
- delete gridContainer.dataset.hasScrollX;
- }
- } else {
- if (gridContainer.scrollWidth > gridContainer.clientWidth) {
- gridContainer.dataset.hasScrollX = "true";
- }
- }
- }
-
- const sizes = new Map();
- container.querySelectorAll("[data-column-id]").forEach(c => {
- const columnId = c.dataset.columnId;
- if (!columnId) {
- console.debug("getColumnSizes: can't find id on:", c);
- return;
- }
-
- sizes.set(columnId, c.getBoundingClientRect().width);
- });
- gridSizeStore.updateColumnSizes(sizes.values().toArray());
- },
- [gridSizeStore]
- );
-
- useEffect(() => {
- const observer = new ResizeObserver(resizeCallback);
-
- columnsStore.visibleColumns.forEach(c => {
- if (c.headerElementRef) observer.observe(c.headerElementRef);
- });
-
- return () => {
- observer.disconnect();
- };
- }, [resizeCallback, columnsStore.visibleColumns]);
-
- return (
-
- {config.checkboxColumnEnabled &&
}
- {columnsStore.visibleColumns.map(c => (
-
c.setHeaderElementRef(ref)}
- >
- ))}
- {config.selectorColumnEnabled &&
}
-
- );
-}
diff --git a/packages/pluggableWidgets/datagrid-web/src/components/Widget.tsx b/packages/pluggableWidgets/datagrid-web/src/components/Widget.tsx
index 8a3809b2b6..bce68e5755 100644
--- a/packages/pluggableWidgets/datagrid-web/src/components/Widget.tsx
+++ b/packages/pluggableWidgets/datagrid-web/src/components/Widget.tsx
@@ -13,7 +13,6 @@ import { WidgetFooter } from "./WidgetFooter";
import { WidgetHeader } from "./WidgetHeader";
import { WidgetRoot } from "./WidgetRoot";
import { WidgetTopBar } from "./WidgetTopBar";
-import { MockHeader } from "./MockHeader";
export function Widget(props: { onExportCancel?: () => void }): ReactElement {
return (
@@ -27,7 +26,6 @@ export function Widget(props: { onExportCancel?: () => void }): ReactElement {
-
diff --git a/packages/pluggableWidgets/datagrid-web/src/components/__tests__/Grid.spec.tsx b/packages/pluggableWidgets/datagrid-web/src/components/__tests__/Grid.spec.tsx
index fd42081e81..d95e0206df 100644
--- a/packages/pluggableWidgets/datagrid-web/src/components/__tests__/Grid.spec.tsx
+++ b/packages/pluggableWidgets/datagrid-web/src/components/__tests__/Grid.spec.tsx
@@ -1,9 +1,12 @@
import { render } from "@testing-library/react";
import { ContainerProvider } from "brandi-react";
+import { setupIntersectionObserverStub } from "@mendix/widget-plugin-test-utils";
import { createDatagridContainer } from "../../model/containers/createDatagridContainer";
import { mockContainerProps } from "../../utils/test-utils";
import { Grid } from "../Grid";
+setupIntersectionObserverStub();
+
describe("Grid", () => {
it("renders without crashing", () => {
const props = mockContainerProps();
diff --git a/packages/pluggableWidgets/datagrid-web/src/model/hooks/useInfiniteControl.tsx b/packages/pluggableWidgets/datagrid-web/src/model/hooks/useInfiniteControl.tsx
index 50da655ed0..e1bed0d181 100644
--- a/packages/pluggableWidgets/datagrid-web/src/model/hooks/useInfiniteControl.tsx
+++ b/packages/pluggableWidgets/datagrid-web/src/model/hooks/useInfiniteControl.tsx
@@ -6,26 +6,26 @@ import { VIRTUAL_SCROLLING_OFFSET } from "../stores/GridSize.store";
export function useInfiniteControl(): [trackBodyScrolling: ((e: any) => void) | undefined] {
const gridSizeStore = useGridSizeStore();
- const isVisible = useOnScreen(gridSizeStore.gridBodyRef as RefObject);
+ const isVisible = useOnScreen(gridSizeStore.gridContainerRef as RefObject);
- const trackBodyScrolling = useCallback(
+ const trackTableScrolling = useCallback(
(e: UIEvent) => {
const target = e.target as HTMLElement;
- const head = gridSizeStore.gridHeaderRef.current;
- if (head) {
- // synchronize header position to the body as they are decoupled
- // we don't use state to optimize speed as we
- // don't want a re-render.
- head.scrollTo({ left: target.scrollLeft });
-
+ const container = gridSizeStore.gridContainerRef.current;
+ if (container) {
// this is cosmetic, needed to provide nice shadows when body is scrolled
- head.dataset.scrolledY = target.scrollTop > 0 ? "true" : "false";
- head.dataset.scrolledX = target.scrollLeft > 0 ? "true" : "false";
+ if (target.scrollTop > 0) {
+ container.dataset.scrolledY = "true";
+ } else {
+ delete container.dataset.scrolledY;
+ }
+ if (target.scrollLeft > 0) {
+ container.dataset.scrolledX = "true";
+ } else {
+ delete container.dataset.scrolledX;
+ }
}
- // we need to determine scrollbar width to calculate header size correctly in css
- gridSizeStore.setScrollBarSize(target.offsetWidth - target.clientWidth);
-
/**
* In Windows OS the result of first expression returns a non integer and result in never loading more, require floor to solve.
* note: Math floor sometimes result in incorrect integer value,
@@ -42,26 +42,9 @@ export function useInfiniteControl(): [trackBodyScrolling: ((e: any) => void) |
);
useEffect(() => {
- const timer = setTimeout(() => isVisible && gridSizeStore.lockGridBodyHeight(), 100);
+ const timer = setTimeout(() => isVisible && gridSizeStore.lockGridContainerHeight(), 100);
return () => clearTimeout(timer);
});
- useEffect(() => {
- const observeTarget = gridSizeStore.gridContainerRef.current;
- if (!gridSizeStore.hasVirtualScrolling || !observeTarget) return;
-
- const resizeObserver = new ResizeObserver(entries => {
- for (const entry of entries) {
- gridSizeStore.setGridWidth(entry.contentRect.width);
- }
- });
-
- resizeObserver.observe(observeTarget);
-
- return () => {
- resizeObserver.unobserve(observeTarget);
- };
- }, [gridSizeStore]);
-
- return [gridSizeStore.hasVirtualScrolling ? trackBodyScrolling : undefined];
+ return [gridSizeStore.hasVirtualScrolling ? trackTableScrolling : undefined];
}
diff --git a/packages/pluggableWidgets/datagrid-web/src/model/models/grid.model.ts b/packages/pluggableWidgets/datagrid-web/src/model/models/grid.model.ts
index e8c99f06a3..90144c34f6 100644
--- a/packages/pluggableWidgets/datagrid-web/src/model/models/grid.model.ts
+++ b/packages/pluggableWidgets/datagrid-web/src/model/models/grid.model.ts
@@ -18,10 +18,7 @@ export function gridStyleAtom(
checkboxColumn: config.checkboxColumnEnabled,
selectorColumn: config.selectorColumnEnabled
}),
- "--widgets-grid-template-columns-head": gridSizeStore.templateColumnsHead,
- "--widgets-grid-body-height": asPx(gridSizeStore.gridBodyHeight),
- "--widgets-grid-width": asPx(gridSizeStore.gridWidth),
- "--widgets-grid-scrollbar-size": asPx(gridSizeStore.scrollBarSize)
+ "--widgets-grid-table-height": asPx(gridSizeStore.gridContainerHeight)
}) as CSSProperties
);
}
diff --git a/packages/pluggableWidgets/datagrid-web/src/model/stores/GridSize.store.ts b/packages/pluggableWidgets/datagrid-web/src/model/stores/GridSize.store.ts
index b3a11b6688..77c9e08d89 100644
--- a/packages/pluggableWidgets/datagrid-web/src/model/stores/GridSize.store.ts
+++ b/packages/pluggableWidgets/datagrid-web/src/model/stores/GridSize.store.ts
@@ -1,6 +1,6 @@
import { SetPageAction } from "@mendix/widget-plugin-grid/pagination/main";
import { ComputedAtom } from "@mendix/widget-plugin-mobx-kit/main";
-import { action, computed, makeAutoObservable, observable } from "mobx";
+import { action, makeAutoObservable, observable } from "mobx";
import { createRef } from "react";
import { PaginationConfig } from "../../features/pagination/pagination.config";
@@ -11,10 +11,7 @@ export class GridSizeStore {
gridBodyRef = createRef();
gridHeaderRef = createRef();
- scrollBarSize?: number;
- gridWidth?: number;
- gridBodyHeight?: number;
- columnSizes?: number[];
+ gridContainerHeight?: number;
private lockedAtPageSize?: number;
@@ -30,19 +27,8 @@ export class GridSizeStore {
gridHeaderRef: false,
lockedAtPageSize: false,
- scrollBarSize: observable,
- setScrollBarSize: action,
-
- gridWidth: observable,
- setGridWidth: action,
-
- gridBodyHeight: observable,
- lockGridBodyHeight: action,
-
- columnSizes: observable,
- updateColumnSizes: action,
-
- templateColumnsHead: computed
+ gridContainerHeight: observable,
+ lockGridContainerHeight: action
});
}
@@ -54,34 +40,12 @@ export class GridSizeStore {
return this.paginationConfig.pagination === "virtualScrolling";
}
- get templateColumnsHead(): string | undefined {
- return this.columnSizes
- ?.map(size => {
- const str = size.toString();
- const dotIndex = str.indexOf(".");
- return `${dotIndex === -1 ? str : str.slice(0, dotIndex + 4)}px`;
- })
- .join(" ");
- }
-
bumpPage(): void {
if (this.hasMoreItems) {
return this.setPageAction(page => page + 1);
}
}
- setScrollBarSize(size: number): void {
- this.scrollBarSize = size;
- }
-
- setGridWidth(size: number | undefined): void {
- this.gridWidth = size;
- }
-
- updateColumnSizes(sizes: number[]): void {
- this.columnSizes = sizes;
- }
-
/**
* Computes the total viewport height of visible rows based on the current page size.
* @returns {number} Total height in pixels of visible rows, or 0 if no rows present.
@@ -101,7 +65,17 @@ export class GridSizeStore {
return totalHeight;
}
- lockGridBodyHeight(): void {
+ computeHeaderViewport(): number {
+ const firstTh = this.gridHeaderRef.current?.querySelector(".th");
+
+ if (!firstTh) {
+ return 0;
+ }
+
+ return firstTh.offsetHeight;
+ }
+
+ lockGridContainerHeight(): void {
if (!this.hasVirtualScrolling || !this.hasMoreItems) {
return;
}
@@ -109,31 +83,34 @@ export class GridSizeStore {
// Reset the locked height when page size changes so layout is recomputed
// for the new number of rows (e.g. switching from 10 → 5 rows).
const currentPageSize = this.pageSizeAtom.get();
- if (this.gridBodyHeight !== undefined && this.lockedAtPageSize !== currentPageSize) {
- this.gridBodyHeight = undefined;
+ if (this.gridContainerHeight !== undefined && this.lockedAtPageSize !== currentPageSize) {
+ this.gridContainerHeight = undefined;
this.lockedAtPageSize = undefined;
}
- const gridBody = this.gridBodyRef.current;
- if (!gridBody || this.gridBodyHeight !== undefined) {
+ const gridContainer = this.gridContainerRef.current;
+ if (!gridContainer || this.gridContainerHeight !== undefined) {
return;
}
- const viewportHeight = this.computeBodyViewport();
+ const bodyViewportHeight = this.computeBodyViewport();
+ const headerViewportHeight = this.computeHeaderViewport();
// Don't lock height before the grid body has rendered content.
// clientHeight is 0 when the element has no layout yet, which would
// produce a negative height and break scrolling.
- if (viewportHeight <= 0) {
+ if (bodyViewportHeight <= 0) {
return;
}
+ const fullHeight = bodyViewportHeight + headerViewportHeight;
+
// If content already overflows the container (fixed-height grid), do not subtract the
// pre-fetch offset — that would hide the last rows and trigger the next page too early.
// Only subtract the offset when the grid does not yet overflow (auto-height grid) so
// that we create a small synthetic overflow that makes the body scrollable.
- const overflows = gridBody.scrollHeight > viewportHeight;
- this.gridBodyHeight = viewportHeight - (overflows ? 0 : VIRTUAL_SCROLLING_OFFSET);
+ const overflows = gridContainer.scrollHeight > fullHeight;
+ this.gridContainerHeight = fullHeight - (overflows ? 0 : VIRTUAL_SCROLLING_OFFSET);
this.lockedAtPageSize = currentPageSize;
}
}
diff --git a/packages/pluggableWidgets/popup-menu-web/src/__tests__/__snapshots__/Menu.spec.tsx.snap b/packages/pluggableWidgets/popup-menu-web/src/__tests__/__snapshots__/Menu.spec.tsx.snap
index d2eb16172f..cecd9fde46 100644
--- a/packages/pluggableWidgets/popup-menu-web/src/__tests__/__snapshots__/Menu.spec.tsx.snap
+++ b/packages/pluggableWidgets/popup-menu-web/src/__tests__/__snapshots__/Menu.spec.tsx.snap
@@ -17,6 +17,7 @@ exports[`Menu renders menu 1`] = `
diff --git a/packages/pluggableWidgets/tooltip-web/src/components/Tooltip.tsx b/packages/pluggableWidgets/tooltip-web/src/components/Tooltip.tsx
index 13637494c6..231885c1c3 100644
--- a/packages/pluggableWidgets/tooltip-web/src/components/Tooltip.tsx
+++ b/packages/pluggableWidgets/tooltip-web/src/components/Tooltip.tsx
@@ -48,6 +48,7 @@ export const Tooltip = (props: TooltipProps): ReactElement => {
ref={refs?.setFloating}
style={floatingStyles}
{...getFloatingProps?.()}
+ data-overlay-content
>
{renderMethod === "text" ? textMessage : htmlMessage}
diff --git a/packages/pluggableWidgets/tooltip-web/src/components/__tests__/__snapshots__/Tooltip.spec.tsx.snap b/packages/pluggableWidgets/tooltip-web/src/components/__tests__/__snapshots__/Tooltip.spec.tsx.snap
index 21d786034a..0c48903965 100644
--- a/packages/pluggableWidgets/tooltip-web/src/components/__tests__/__snapshots__/Tooltip.spec.tsx.snap
+++ b/packages/pluggableWidgets/tooltip-web/src/components/__tests__/__snapshots__/Tooltip.spec.tsx.snap
@@ -19,6 +19,7 @@ exports[`Tooltip render DOM structure 1`] = `
+
{isOpen &&
diff --git a/packages/shared/widget-plugin-filtering/src/controls/filter-selector/FilterSelector.tsx b/packages/shared/widget-plugin-filtering/src/controls/filter-selector/FilterSelector.tsx
index 7e67ab79be..8d3b0f89f4 100644
--- a/packages/shared/widget-plugin-filtering/src/controls/filter-selector/FilterSelector.tsx
+++ b/packages/shared/widget-plugin-filtering/src/controls/filter-selector/FilterSelector.tsx
@@ -42,6 +42,7 @@ export function FilterSelector(props: FilterSelectorProps): ReactElement {
className={classNames("filter-selectors", { hidden: !open, visible: open })}
{...listboxProps}
style={floatingStyles}
+ data-overlay-content={open || undefined}
>
{open &&
options.map((item, index) => (