Skip to content

Commit ba52a60

Browse files
committed
fix: restore sort icon state, add dragndropdesign mode and react icon
1 parent 939bc1d commit ba52a60

File tree

5 files changed

+84
-51
lines changed

5 files changed

+84
-51
lines changed

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,17 +139,24 @@ $root: ".widget-datagrid";
139139
width: 14px;
140140
padding: 0;
141141
flex-grow: 0;
142+
flex-shrink: 0;
142143
display: flex;
143144
justify-content: center;
145+
align-self: normal;
144146
z-index: 1;
145147

146148
&:hover {
147149
background-color: var(--brand-primary-50, $brand-light);
148-
color: var(--brand-primary, $brand-primary);
150+
svg {
151+
color: var(--brand-primary, $brand-primary);
152+
}
149153
}
150-
:active {
154+
&:active {
151155
cursor: grabbing;
152156
}
157+
svg {
158+
margin: 0;
159+
}
153160
}
154161

155162
.drag-handle + .column-caption {

packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import { GUID, ObjectItem } from "mendix";
44
import { Selectable } from "mendix/preview/Selectable";
55
import { createContext, CSSProperties, PropsWithChildren, ReactElement, ReactNode, useContext } from "react";
66
import { ColumnsPreviewType, DatagridPreviewProps } from "typings/DatagridProps";
7+
import { DragHandle } from "./components/DragHandle";
78
import { FaArrowsAltV } from "./components/icons/FaArrowsAltV";
89
import { FaEye } from "./components/icons/FaEye";
910
import { ColumnPreview } from "./helpers/ColumnPreview";
11+
1012
import "./ui/DatagridPreview.scss";
1113

1214
declare module "mendix/preview/Selectable" {
@@ -157,7 +159,7 @@ function GridHeader(): ReactNode {
157159
}
158160

159161
function ColumnHeader({ column }: { column: ColumnsPreviewType }): ReactNode {
160-
const { columnsFilterable, columnsSortable, columnsHidable } = useProps();
162+
const { columnsFilterable, columnsSortable, columnsHidable, columnsDraggable } = useProps();
161163
const columnPreview = new ColumnPreview(column, 0);
162164
const caption = columnPreview.header;
163165
const canSort = columnsSortable && columnPreview.canSort;
@@ -172,6 +174,9 @@ function ColumnHeader({ column }: { column: ColumnsPreviewType }): ReactNode {
172174
>
173175
<div className="column-container">
174176
<div className="column-header">
177+
{columnsDraggable && (
178+
<DragHandle draggable={false} onDragStart={() => {}} onDragEnd={() => {}} />
179+
)}
175180
<span>{caption.length > 0 ? caption : "\u00a0"}</span>
176181
{canSort && <FaArrowsAltV />}
177182
</div>

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

Lines changed: 8 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import classNames from "classnames";
2-
import { DragEvent, DragEventHandler, HTMLAttributes, KeyboardEvent, MouseEvent, ReactElement, ReactNode } from "react";
2+
import { HTMLAttributes, KeyboardEvent, ReactElement, ReactNode } from "react";
3+
import { DragHandle } from "./DragHandle";
34
import { FaArrowsAltV } from "./icons/FaArrowsAltV";
45
import { FaLongArrowAltDown } from "./icons/FaLongArrowAltDown";
56
import { FaLongArrowAltUp } from "./icons/FaLongArrowAltUp";
67
import { useColumn, useHeaderDragnDropVM } from "../model/hooks/injection-hooks";
78
import { observer } from "mobx-react-lite";
9+
import { SortDirection } from "../typings/sorting";
810

9-
interface DragHandleProps {
10-
draggable: boolean;
11-
onDragStart?: DragEventHandler<HTMLSpanElement>;
12-
onDragEnd?: DragEventHandler<HTMLSpanElement>;
11+
interface SortIconProps {
12+
direction: SortDirection | undefined;
1313
}
1414

1515
export const ColumnHeader = observer(function ColumnHeader(): ReactElement {
@@ -30,53 +30,13 @@ export const ColumnHeader = observer(function ColumnHeader(): ReactElement {
3030
<DragHandle draggable={vm.isDraggable} onDragStart={vm.handleDragStart} onDragEnd={vm.handleDragEnd} />
3131
)}
3232
<span className="column-caption">{caption.length > 0 ? caption : "\u00a0"}</span>
33-
{canSort ? <SortIcon /> : null}
33+
{canSort ? <SortIcon direction={column.sortDir} /> : null}
3434
</div>
3535
);
3636
});
3737

38-
function DragHandle({ draggable, onDragStart, onDragEnd }: DragHandleProps): ReactElement {
39-
const handleMouseDown = (e: MouseEvent<HTMLSpanElement>): void => {
40-
// Only stop propagation, don't prevent default - we need default for drag to work
41-
e.stopPropagation();
42-
};
43-
44-
const handleClick = (e: MouseEvent<HTMLSpanElement>): void => {
45-
// Stop click events from bubbling to prevent sorting
46-
e.stopPropagation();
47-
e.preventDefault();
48-
};
49-
50-
const handleDragStart = (e: DragEvent<HTMLSpanElement>): void => {
51-
// Don't stop propagation here - let the drag start properly
52-
if (onDragStart) {
53-
onDragStart(e);
54-
}
55-
};
56-
57-
const handleDragEnd = (e: DragEvent<HTMLSpanElement>): void => {
58-
if (onDragEnd) {
59-
onDragEnd(e);
60-
}
61-
};
62-
63-
return (
64-
<span
65-
className="drag-handle"
66-
draggable={draggable}
67-
onDragStart={handleDragStart}
68-
onDragEnd={handleDragEnd}
69-
onMouseDown={handleMouseDown}
70-
onClick={handleClick}
71-
>
72-
73-
</span>
74-
);
75-
}
76-
77-
function SortIcon(): ReactNode {
78-
const column = useColumn();
79-
switch (column.sortDir) {
38+
function SortIcon({ direction }: SortIconProps): ReactNode {
39+
switch (direction) {
8040
case "asc":
8141
return <FaLongArrowAltUp />;
8242
case "desc":
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { DragEvent, DragEventHandler, MouseEvent, ReactElement } from "react";
2+
import { FaGripVertical } from "./icons/FaGripVertical";
3+
4+
interface DragHandleProps {
5+
draggable: boolean;
6+
onDragStart?: DragEventHandler<HTMLSpanElement>;
7+
onDragEnd?: DragEventHandler<HTMLSpanElement>;
8+
}
9+
export function DragHandle({ draggable, onDragStart, onDragEnd }: DragHandleProps): ReactElement {
10+
const handleMouseDown = (e: MouseEvent<HTMLSpanElement>): void => {
11+
// Only stop propagation, don't prevent default - we need default for drag to work
12+
e.stopPropagation();
13+
};
14+
15+
const handleClick = (e: MouseEvent<HTMLSpanElement>): void => {
16+
// Stop click events from bubbling to prevent sorting
17+
e.stopPropagation();
18+
e.preventDefault();
19+
};
20+
21+
const handleDragStart = (e: DragEvent<HTMLSpanElement>): void => {
22+
// Don't stop propagation here - let the drag start properly
23+
if (onDragStart) {
24+
onDragStart(e);
25+
}
26+
};
27+
28+
const handleDragEnd = (e: DragEvent<HTMLSpanElement>): void => {
29+
if (onDragEnd) {
30+
onDragEnd(e);
31+
}
32+
};
33+
34+
return (
35+
<span
36+
className="drag-handle"
37+
draggable={draggable}
38+
onDragStart={handleDragStart}
39+
onDragEnd={handleDragEnd}
40+
onMouseDown={handleMouseDown}
41+
onClick={handleClick}
42+
>
43+
<FaGripVertical />
44+
</span>
45+
);
46+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { ReactElement } from "react";
2+
3+
/**
4+
* Custom drag handle icon with 6 aligned dots in 3 rows
5+
*/
6+
export function FaGripVertical(): ReactElement {
7+
return (
8+
<svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
9+
<path
10+
fill="currentColor"
11+
d="M96 64c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm128 0c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm-128 160c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm128 0c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm-128 160c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm128 0c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32z"
12+
></path>
13+
</svg>
14+
);
15+
}

0 commit comments

Comments
 (0)