diff --git a/package.json b/package.json
index 5d72d8091f..80033981ae 100644
--- a/package.json
+++ b/package.json
@@ -50,6 +50,7 @@
"@codemirror/state": "^6.5.2",
"@codemirror/view": "^6.38.1",
"@mendix/pluggable-widgets-tools": "10.21.2",
+ "@prettier/plugin-xml": ">=3.4.1",
"@testing-library/react": ">=15.0.6",
"@types/big.js": "^6.2.2",
"@types/node": "~22.14.0",
@@ -75,7 +76,6 @@
"mime-types": "patches/mime-types.patch",
"mobx-react-lite@4.0.7": "patches/mobx-react-lite@4.0.7.patch",
"mobx@6.12.3": "patches/mobx@6.12.3.patch",
- "rc-trigger": "patches/rc-trigger.patch",
"react-big-calendar@0.19.2": "patches/react-big-calendar@0.19.2.patch",
"react-dropzone": "patches/react-dropzone.patch"
},
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 79b2ac631b..6158e3d77d 100644
--- a/packages/modules/data-widgets/src/themesource/datawidgets/web/_datagrid.scss
+++ b/packages/modules/data-widgets/src/themesource/datawidgets/web/_datagrid.scss
@@ -307,52 +307,6 @@ $root: ".widget-datagrid";
width: 100%;
}
-.pagination-bar {
- display: flex;
- justify-content: flex-end;
- white-space: nowrap;
- align-items: baseline;
- margin: 16px;
- color: $pagination-caption-color;
-
- .paging-status {
- padding: 0 8px 0;
- }
-
- .pagination-button {
- padding: 6px;
- color: var(--gray-darker, $gray-darker);
- border-color: transparent;
- background-color: transparent;
-
- &:hover {
- color: var(--brand-primary, $brand-primary);
- border-color: transparent;
- background-color: transparent;
- }
-
- &:disabled {
- border-color: transparent;
- background-color: transparent;
- }
-
- &:focus:not(:focus-visible) {
- outline: none;
- }
-
- &:focus-visible {
- outline: 1px solid var(--brand-primary, $brand-primary);
- }
- }
- .pagination-icon {
- position: relative;
- top: 4px;
- display: inline-block;
- width: 20px;
- height: 20px;
- }
-}
-
/* Column selector for hidable columns outside DG context */
/* List of columns to select */
.column-selectors {
@@ -522,6 +476,10 @@ $root: ".widget-datagrid";
}
}
+.widget-datagrid .progress-bar {
+ margin: var(--spacing-medium, 16px);
+}
+
.widget-datagrid .widget-datagrid-load-more {
display: block !important;
margin: var(--spacing-small, 8px) 0;
diff --git a/packages/modules/data-widgets/src/themesource/datawidgets/web/_gallery.scss b/packages/modules/data-widgets/src/themesource/datawidgets/web/_gallery.scss
index 4848ae75a7..38885d75b2 100644
--- a/packages/modules/data-widgets/src/themesource/datawidgets/web/_gallery.scss
+++ b/packages/modules/data-widgets/src/themesource/datawidgets/web/_gallery.scss
@@ -5,6 +5,7 @@
========================================================================== */
$gallery-screen-lg: $screen-lg;
$gallery-screen-md: $screen-md;
+$root: ".widget-gallery";
@mixin grid-items($number, $suffix) {
@for $i from 1 through $number {
@@ -162,3 +163,19 @@ $gallery-screen-md: $screen-md;
}
}
}
+
+#{$root}-btn-link {
+ cursor: pointer;
+ background: transparent;
+ border: none;
+ color: var(--link-color);
+ padding: 0.3em 0.5em;
+ border-radius: 6px;
+ display: inline-block;
+ white-space: nowrap;
+
+ &:hover,
+ &:focus-visible {
+ background-color: var(--brand-primary-50, #e6e7f2);
+ }
+}
diff --git a/packages/modules/data-widgets/src/themesource/datawidgets/web/_pagination-bar.scss b/packages/modules/data-widgets/src/themesource/datawidgets/web/_pagination-bar.scss
new file mode 100644
index 0000000000..5e9e0e26cf
--- /dev/null
+++ b/packages/modules/data-widgets/src/themesource/datawidgets/web/_pagination-bar.scss
@@ -0,0 +1,44 @@
+.pagination-bar {
+ display: flex;
+ justify-content: flex-end;
+ white-space: nowrap;
+ align-items: baseline;
+ color: $pagination-caption-color;
+
+ .paging-status {
+ padding: 0 8px 0;
+ }
+
+ .pagination-button {
+ padding: 6px;
+ color: var(--gray-darker, $gray-darker);
+ border-color: transparent;
+ background-color: transparent;
+
+ &:hover {
+ color: var(--brand-primary, $brand-primary);
+ border-color: transparent;
+ background-color: transparent;
+ }
+
+ &:disabled {
+ border-color: transparent;
+ background-color: transparent;
+ }
+
+ &:focus:not(:focus-visible) {
+ outline: none;
+ }
+
+ &:focus-visible {
+ outline: 1px solid var(--brand-primary, $brand-primary);
+ }
+ }
+ .pagination-icon {
+ position: relative;
+ top: 4px;
+ display: inline-block;
+ width: 20px;
+ height: 20px;
+ }
+}
diff --git a/packages/modules/data-widgets/src/themesource/datawidgets/web/main.scss b/packages/modules/data-widgets/src/themesource/datawidgets/web/main.scss
index a9c5fb31c7..d27c9fc081 100644
--- a/packages/modules/data-widgets/src/themesource/datawidgets/web/main.scss
+++ b/packages/modules/data-widgets/src/themesource/datawidgets/web/main.scss
@@ -1,5 +1,6 @@
@import "../../../theme/web/custom-variables";
@import "variables";
+@import "pagination-bar";
@import "datagrid";
@import "datagrid-filters";
@import "datagrid-dropdown-filter";
diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx
index c7e8f0b31a..0fb3991f3e 100644
--- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx
+++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx
@@ -1,4 +1,5 @@
import { If } from "@mendix/widget-plugin-component-kit/If";
+import { Pagination as PagingButtons } from "@mendix/widget-plugin-grid/components/Pagination";
import cn from "classnames";
import { GUID, ObjectItem } from "mendix";
import { Selectable } from "mendix/preview/Selectable";
@@ -51,13 +52,18 @@ const numberOfItems = 3;
const cls = {
root: "widget-datagrid",
topBar: "widget-datagrid-top-bar table-header",
+ pagingTop: "widget-datagrid-padding-top",
+ ptStart: "widget-datagrid-tb-start",
+ ptEnd: "widget-datagrid-tb-end",
header: "widget-datagrid-header header-filters",
content: "widget-datagrid-content",
grid: "widget-datagrid-grid table",
gridHeader: "widget-datagrid-grid-head",
gridBody: "widget-datagrid-grid-body table-content",
+ footer: "widget-datagrid-footer table-footer",
pb: "widget-datagrid-padding-bottom",
pbStart: "widget-datagrid-pb-start",
+ pbMid: "widget-datagrid-pb-middle",
pbEnd: "widget-datagrid-pb-end"
};
@@ -79,9 +85,7 @@ export function preview(props: DatagridPreviewProps): ReactElement {
-
-
-
+
);
@@ -96,8 +100,15 @@ function WidgetRoot({ children }: PropsWithChildren): ReactElement {
);
}
-function WidgetTopBar({ children }: PropsWithChildren): ReactElement {
- return
{children}
;
+function WidgetTopBar(): ReactElement {
+ return (
+
+
+
{useTopCounter() ? : null}
+
{usePagingTop() ?
: null}
+
+
+ );
}
function WidgetHeader(): ReactNode {
@@ -113,8 +124,23 @@ function WidgetContent({ children }: PropsWithChildren): ReactElement {
return {children}
;
}
-function WidgetFooter({ children }: PropsWithChildren): ReactElement {
- return {children}
;
+function WidgetFooter(): ReactElement {
+ const props = useProps();
+ return (
+
+
+
{useBottomCounter() ? : null}
+
+ {props.pagination === "loadMore" ? (
+
+ ) : null}
+
+
{usePagingBot() ?
: null}
+
+
+ );
}
function Grid({ children }: PropsWithChildren): ReactElement {
@@ -269,14 +295,36 @@ function EmptyPlaceholder(): ReactElement {
);
}
-function PaddingBottom(): ReactElement {
+const SelectionCounter = (): ReactNode => {
+ const props = useProps();
return (
-
-
-
+
+
+ {props.selectedCountTemplateSingular}
+
+ |
+
);
-}
+};
+
+const Pagination = (): ReactNode => {
+ const props = useProps();
+ return (
+
{}}
+ nextPage={() => {}}
+ numberOfItems={props.pageSize ?? 20}
+ page={0}
+ pageSize={props.pageSize ?? 10}
+ showPagingButtons={"always"}
+ previousPage={() => {}}
+ pagination={props.pagination}
+ />
+ );
+};
function useColumns(): ColumnsPreviewType[] {
const { columns } = useProps();
@@ -320,3 +368,25 @@ function useGridStyle(): CSSProperties {
"--widgets-grid-template-columns": sizes.join(" ")
} as CSSProperties;
}
+
+function useTopCounter(): boolean {
+ const { itemSelection, selectionCounterPosition } = useProps();
+ return itemSelection === "Multi" && selectionCounterPosition === "top";
+}
+
+function useBottomCounter(): boolean {
+ const { itemSelection, selectionCounterPosition } = useProps();
+ return itemSelection === "Multi" && selectionCounterPosition === "bottom";
+}
+
+function usePagingTop(): boolean {
+ const props = useProps();
+ const visible = props.showNumberOfRows || props.pagination === "buttons";
+ return visible && props.pagingPosition !== "bottom";
+}
+
+function usePagingBot(): boolean {
+ const props = useProps();
+ const visible = props.showNumberOfRows || props.pagination === "buttons";
+ return visible && props.pagingPosition !== "top";
+}
diff --git a/packages/pluggableWidgets/datagrid-web/src/components/WidgetFooter.tsx b/packages/pluggableWidgets/datagrid-web/src/components/WidgetFooter.tsx
index ccaf2820ad..5433e25ce2 100644
--- a/packages/pluggableWidgets/datagrid-web/src/components/WidgetFooter.tsx
+++ b/packages/pluggableWidgets/datagrid-web/src/components/WidgetFooter.tsx
@@ -13,11 +13,7 @@ export const WidgetFooter = observer(function WidgetFooter(): ReactElement | nul
const selectionCounterVM = useSelectionCounterViewModel();
const customPagination = useCustomPagination();
- const showFooter =
- selectionCounterVM.isBottomCounterVisible ||
- paging.paginationVisible ||
- paging.showVirtualScrollingWithRowCount ||
- paging.showLoadMore;
+ const showFooter = selectionCounterVM.isBottomCounterVisible || paging.paginationVisible || paging.loadMoreVisible;
if (!showFooter) {
return null;
@@ -31,7 +27,7 @@ export const WidgetFooter = observer(function WidgetFooter(): ReactElement | nul
-
+