Skip to content

Commit 6de3b79

Browse files
committed
fix: virtual scroll rework
1 parent e51dc98 commit 6de3b79

File tree

4 files changed

+44
-55
lines changed

4 files changed

+44
-55
lines changed

packages/modules/data-widgets/src/themesource/datawidgets/web/_datagrid.scss

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -540,40 +540,26 @@ $root: ".widget-datagrid";
540540
margin: 0 auto;
541541
}
542542

543-
:where(.widget-datagrid-grid.infinite-loading) {
543+
.infinite-loading.widget-datagrid-grid-body {
544+
// when virtual scroll is enabled
545+
// we make area that holds rows scrollable
546+
// the area that holds column headers still stands in place
544547
overflow-y: auto;
545548
}
546549

547-
:where(.infinite-loading .widget-datagrid-grid-head .th) {
548-
position: sticky;
549-
z-index: 1;
550-
}
551-
552-
:where(#{$root}-paging-bottom) {
553-
display: flex;
554-
flex-flow: row nowrap;
555-
align-items: center;
556-
}
550+
.widget-datagrid-grid-head,
551+
.widget-datagrid-grid-body {
552+
// this element has to position thier children (columns/headers)
553+
// as grid and have those aligned with the parent grid
554+
display: grid;
557555

558-
:where(#{$root}-pb-start, #{$root}-pb-end, #{$root}-pb-middle) {
559-
flex-grow: 1;
560-
flex-basis: 33.33%;
561-
min-height: 20px;
562-
}
563-
564-
:where(#{$root}-pb-start) {
565-
margin-block: var(--spacing-medium);
566-
padding-inline: var(--spacing-medium);
567-
}
556+
// ensure that header covers all columns of original
557+
// grid and we can place elements to match this
558+
grid-column: 1 / -1;
568559

569-
#{$root}-clear-selection {
570-
cursor: pointer;
571-
background: transparent;
572-
border: none;
573-
text-decoration: underline;
574-
color: var(--link-color);
575-
padding: 0;
576-
display: inline-block;
560+
// this property makes sure we align our own grid columns
561+
// to the columns defined in the global grid
562+
grid-template-columns: subgrid;
577563
}
578564

579565
@keyframes skeleton-loading {

packages/pluggableWidgets/datagrid-web/src/components/Grid.tsx

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,17 @@
11
import classNames from "classnames";
22
import { createElement, JSX, ReactElement } from "react";
3-
import { PaginationEnum } from "../../typings/DatagridProps";
4-
import { useInfiniteControl } from "@mendix/widget-plugin-grid/components/InfiniteBody";
53

64
type P = Omit<JSX.IntrinsicElements["div"], "role" | "ref">;
75

86
export interface GridProps extends P {
9-
paginationType: PaginationEnum;
107
className?: string;
11-
hasMoreItems: boolean;
12-
setPage?: (update: (page: number) => number) => void;
138
}
149

1510
export function Grid(props: GridProps): ReactElement {
16-
const { className, style, paginationType, hasMoreItems, setPage, children, ...rest } = props;
17-
const isInfinite = paginationType === "virtualScrolling";
18-
const [trackScrolling, bodySize, containerRef] = useInfiniteControl({
19-
hasMoreItems,
20-
isInfinite,
21-
setPage
22-
});
11+
const { className, style, children, ...rest } = props;
2312

2413
return (
25-
<div
26-
className={classNames("widget-datagrid-grid table", { "infinite-loading": isInfinite }, className)}
27-
role="grid"
28-
{...rest}
29-
ref={containerRef}
30-
style={isInfinite && bodySize > 0 ? { ...style, maxHeight: bodySize } : style}
31-
onScroll={isInfinite ? trackScrolling : undefined}
32-
>
14+
<div className={classNames("widget-datagrid-grid table", className)} role="grid" style={style} {...rest}>
3315
{children}
3416
</div>
3517
);

packages/pluggableWidgets/datagrid-web/src/components/GridBody.tsx

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import classNames from "classnames";
22
import { createElement, Fragment, ReactElement } from "react";
3-
import { LoadingTypeEnum } from "../../typings/DatagridProps";
3+
import { LoadingTypeEnum, PaginationEnum } from "../../typings/DatagridProps";
44
import { SpinnerLoader } from "./loader/SpinnerLoader";
55
import { RowSkeletonLoader } from "./loader/RowSkeletonLoader";
6+
import { useInfiniteControl } from "@mendix/widget-plugin-grid/components/InfiniteBody";
67

78
interface Props {
89
className?: string;
@@ -14,10 +15,20 @@ interface Props {
1415
columnsSize: number;
1516
rowsSize: number;
1617
pageSize: number;
18+
pagination: PaginationEnum;
19+
hasMoreItems: boolean;
20+
setPage?: (update: (page: number) => number) => void;
1721
}
1822

1923
export function GridBody(props: Props): ReactElement {
20-
const { children } = props;
24+
const { children, pagination, hasMoreItems, setPage } = props;
25+
26+
const isInfinite = pagination === "virtualScrolling";
27+
const [trackScrolling, bodySize, containerRef] = useInfiniteControl({
28+
hasMoreItems,
29+
isInfinite,
30+
setPage
31+
});
2132

2233
const content = (): React.ReactElement => {
2334
if (props.isFirstLoad) {
@@ -32,7 +43,17 @@ export function GridBody(props: Props): ReactElement {
3243
};
3344

3445
return (
35-
<div className={classNames("widget-datagrid-grid-body table-content", props.className)} role="rowgroup">
46+
<div
47+
className={classNames(
48+
"widget-datagrid-grid-body table-content",
49+
{ "infinite-loading": isInfinite },
50+
props.className
51+
)}
52+
style={isInfinite && bodySize > 0 ? { maxHeight: `${bodySize}px` } : {}}
53+
role="rowgroup"
54+
ref={containerRef}
55+
onScroll={isInfinite ? trackScrolling : undefined}
56+
>
3657
{content()}
3758
</div>
3859
);

packages/pluggableWidgets/datagrid-web/src/components/Widget.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,6 @@ const Main = observer(<C extends GridColumn>(props: WidgetProps<C>): ReactElemen
166166
<Grid
167167
aria-multiselectable={selectionEnabled ? selectActionHelper.selectionType === "Multi" : undefined}
168168
style={cssGridStyles}
169-
setPage={setPage}
170-
paginationType={paginationType}
171-
hasMoreItems={hasMoreItems}
172169
>
173170
<GridHeader
174171
availableColumns={props.availableColumns}
@@ -195,6 +192,9 @@ const Main = observer(<C extends GridColumn>(props: WidgetProps<C>): ReactElemen
195192
columnsSize={visibleColumns.length}
196193
rowsSize={rows.length}
197194
pageSize={pageSize}
195+
pagination={props.paginationType}
196+
hasMoreItems={hasMoreItems}
197+
setPage={setPage}
198198
>
199199
<RowsRenderer
200200
preview={props.preview ?? false}

0 commit comments

Comments
 (0)