Skip to content
Open
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -681,3 +633,7 @@ $root: ".widget-datagrid";
}
}
}

[data-overlay-content] {
z-index: 15;
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export function ComboboxMenuWrapper(props: ComboboxMenuWrapperProps): ReactEleme
}
: style
}
data-overlay-content={isOpen || undefined}
>
{menuHeaderContent && (
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export function DatePicker(props: DatePickerProps): ReactElement {
</span>
<ReactDatePicker
{...staticProps}
popperContainer={({ children }) => (props.expanded ? <div data-overlay-content>{children}</div> : null)}
allowSameDay={false}
ariaLabelledBy={`${props.id}-label`}
autoFocus={false}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand All @@ -17,6 +19,7 @@ export const Grid = observer(function Grid(props: PropsWithChildren): ReactEleme
role="grid"
style={style}
ref={gridSizeStore.gridContainerRef}
onScroll={handleScroll}
>
{props.children}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<div
className={"widget-datagrid-grid-body table-content"}
role="rowgroup"
ref={gridSizeStore.gridBodyRef}
onScroll={handleScroll}
>
<div className={"widget-datagrid-grid-body table-content"} role="rowgroup" ref={gridSizeStore.gridBodyRef}>
<ContentGuard>{children}</ContentGuard>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export function Header(props: HeaderProps): ReactElement {
onDrop={draggableProps.onDrop}
onDragEnter={draggableProps.onDragEnter}
onDragOver={draggableProps.onDragOver}
ref={ref => column.setHeaderElementRef(ref)}
>
<div
className={classNames("column-container")}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand All @@ -27,7 +26,6 @@ export function Widget(props: { onExportCancel?: () => void }): ReactElement {
<RefreshStatus />
<GridBody>
<RowsRenderer />
<MockHeader />
<EmptyPlaceholder />
</GridBody>
</Grid>
Expand Down
Original file line number Diff line number Diff line change
@@ -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();
Expand Down
Loading
Loading