Skip to content

Commit 03335bb

Browse files
committed
refactor: simplify boolean expressions
1 parent e083ab3 commit 03335bb

24 files changed

+810
-619
lines changed

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

Lines changed: 73 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -22,51 +22,14 @@ $root: ".widget-datagrid";
2222
background-color: var(--bg-color-secondary, $bg-color-secondary);
2323
border-width: 0;
2424
border-color: var(--grid-border-color, $grid-border-color);
25-
padding: 0 var(--spacing-medium, $spacing-medium);
25+
padding: var(--spacing-medium, $spacing-medium);
2626
top: 0;
2727
min-width: 0;
2828
position: relative;
2929
}
3030
}
3131

3232
.th {
33-
&.dragging {
34-
opacity: 0.5;
35-
&.dragging-over-self {
36-
opacity: 0.8;
37-
}
38-
}
39-
40-
&.drop-after:after,
41-
&.drop-before:after {
42-
content: "";
43-
position: absolute;
44-
top: 0;
45-
height: 100%;
46-
width: var(--spacing-smaller, $spacing-smaller);
47-
background-color: var(--brand-primary, $dragging-color-effect);
48-
49-
z-index: 1;
50-
}
51-
52-
&.drop-before {
53-
&:after {
54-
left: 0;
55-
}
56-
&:not(:first-child):after {
57-
transform: translateX(-50%);
58-
}
59-
}
60-
61-
&.drop-after {
62-
&:after {
63-
right: 0;
64-
}
65-
&:not(:last-child):after {
66-
transform: translateX(50%);
67-
}
68-
}
69-
7033
/* Clickable column header (Sortable) */
7134
.clickable {
7235
cursor: pointer;
@@ -78,6 +41,8 @@ $root: ".widget-datagrid";
7841
align-self: stretch;
7942
cursor: col-resize;
8043
margin-right: -12px;
44+
margin-top: calc(0px - var(--spacing-medium, 16px));
45+
margin-bottom: calc(0px - var(--spacing-medium, 16px));
8146

8247
&:hover .column-resizer-bar {
8348
background-color: var(--brand-primary, $brand-primary);
@@ -92,24 +57,31 @@ $root: ".widget-datagrid";
9257
}
9358
}
9459

60+
&.locked-drag-active {
61+
z-index: 2;
62+
}
63+
64+
&.dragging-over-self {
65+
opacity: 0.25;
66+
}
67+
9568
/* Drag handle */
9669
.drag-handle {
9770
cursor: grab;
9871
pointer-events: auto;
9972
position: relative;
100-
padding: 4px;
101-
// margin-inline-end: 4px;
73+
width: var(--spacing-medium, $spacing-medium);
74+
padding: 0;
10275
flex-grow: 0;
10376
flex-shrink: 0;
10477
display: flex;
10578
justify-content: center;
106-
align-self: normal;
79+
align-self: center;
10780
z-index: 1;
10881
opacity: 0;
10982
transition: opacity 0.15s ease;
11083

11184
&:hover {
112-
// background-color: var(--brand-primary-50, $brand-light);
11385
svg {
11486
color: var(--brand-primary, $brand-primary);
11587
}
@@ -120,14 +92,12 @@ $root: ".widget-datagrid";
12092
&:focus-visible {
12193
opacity: 1;
12294
}
123-
svg {
95+
> svg {
12496
margin: 0;
125-
width: 8px;
12697
}
12798
}
12899

129-
&:hover .drag-handle,
130-
&:focus-within .drag-handle {
100+
&:hover .drag-handle {
131101
opacity: 1;
132102
}
133103

@@ -136,9 +106,19 @@ $root: ".widget-datagrid";
136106
background-color: var(--brand-primary-50, $brand-light);
137107
}
138108

139-
/* Remove left padding when drag handle is present */
140-
&:has(.drag-handle) {
141-
padding-left: 0;
109+
/* Drag preview (dnd-kit) should look like hovered header */
110+
&.drag-preview {
111+
background-color: var(--brand-primary-50, $brand-light);
112+
box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.25);
113+
border: 1px solid var(--gray-light, $gray-light);
114+
115+
.drag-handle {
116+
opacity: 1;
117+
118+
svg {
119+
color: var(--brand-primary, $brand-primary);
120+
}
121+
}
142122
}
143123

144124
/* Content of the column header */
@@ -148,7 +128,6 @@ $root: ".widget-datagrid";
148128
flex-grow: 1;
149129
align-self: stretch;
150130
min-width: 0;
151-
padding: var(--spacing-small, $spacing-small) 0;
152131

153132
&:not(:has(.filter)) {
154133
.column-header {
@@ -164,7 +143,12 @@ $root: ".widget-datagrid";
164143
align-items: baseline;
165144
font-weight: 600;
166145

167-
span {
146+
.column-caption {
147+
user-select: text;
148+
cursor: text;
149+
}
150+
151+
span:not(.drag-handle) {
168152
min-width: 0;
169153
flex-grow: 1;
170154
text-overflow: ellipsis;
@@ -174,26 +158,56 @@ $root: ".widget-datagrid";
174158
}
175159

176160
svg {
177-
margin-left: 8px;
161+
margin-inline-start: 8px;
178162
flex: 0 0 var(--btn-font-size, $btn-font-size);
179163
color: var(--gray-dark, $gray-dark);
180164
height: var(--btn-font-size, $btn-font-size);
181165
align-self: center;
182166
}
183167

168+
.sort-button {
169+
background: none;
170+
border: none;
171+
padding: 0;
172+
cursor: pointer;
173+
display: flex;
174+
align-items: center;
175+
font-size: inherit;
176+
color: inherit;
177+
height: 100%;
178+
179+
&:focus:not(:focus-visible) {
180+
outline: none;
181+
}
182+
183+
&:focus-visible {
184+
outline: 1px solid var(--brand-primary, $brand-primary);
185+
}
186+
}
187+
184188
&:focus:not(:focus-visible) {
185189
outline: none;
186190
}
187191

188192
&:focus-visible {
189193
outline: 1px solid var(--brand-primary, $brand-primary);
190194
}
195+
196+
&:has(.drag-handle) {
197+
margin-inline-start: calc(var(--spacing-medium, 16px) * -1 + 1px);
198+
.drag-handle svg {
199+
flex: none;
200+
margin: 0;
201+
}
202+
}
191203
}
192204

193205
/* Header filter */
194206
.filter {
195207
display: flex;
196-
margin-top: 4px;
208+
> * {
209+
margin-top: 4px;
210+
}
197211
> .form-group {
198212
margin-bottom: 0;
199213
}
@@ -351,6 +365,12 @@ $root: ".widget-datagrid";
351365
}
352366
}
353367

368+
.table-compact .table .th:hover .column-header:has(.drag-handle),
369+
.table-compact .table .th.drag-preview .column-header:has(.drag-handle) {
370+
margin-inline-start: 0;
371+
transition: margin-inline-start 0.2s ease;
372+
}
373+
354374
:where(.table .th .filter input:not([type="checkbox"])) {
355375
font-weight: normal;
356376
flex-grow: 1;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ $brand-light: #e6eaff !default;
1313
$grid-selected-row-background: $brand-light !default;
1414

1515
// Text and icon colors
16+
$gray-light: #6c7180 !default;
1617
$gray-dark: #606671 !default;
1718
$gray-darker: #3b4251 !default;
1819
$pagination-caption-color: #0a1325 !default;

packages/pluggableWidgets/datagrid-web/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66

77
## [Unreleased]
88

9+
### Breaking changes
10+
11+
- The DOM structure is rewritten, which may break existing CSS styling. We recommend checking the custom styling if there is any in your project.
12+
913
### Fixed
1014

1115
- We added missing Dutch translations for Datagrid 2.

packages/pluggableWidgets/datagrid-web/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
"verify": "rui-verify-package-format"
4242
},
4343
"dependencies": {
44+
"@dnd-kit/core": "^6.3.1",
45+
"@dnd-kit/sortable": "^10.0.0",
46+
"@dnd-kit/utilities": "^3.2.2",
4447
"@floating-ui/react": "^0.26.27",
4548
"@mendix/widget-plugin-component-kit": "workspace:*",
4649
"@mendix/widget-plugin-external-events": "workspace:*",

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ 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";
87
import { FaArrowsAltV } from "./components/icons/FaArrowsAltV";
98
import { FaEye } from "./components/icons/FaEye";
109
import { ColumnPreview } from "./helpers/ColumnPreview";
@@ -159,7 +158,7 @@ function GridHeader(): ReactNode {
159158
}
160159

161160
function ColumnHeader({ column }: { column: ColumnsPreviewType }): ReactNode {
162-
const { columnsFilterable, columnsSortable, columnsHidable, columnsDraggable } = useProps();
161+
const { columnsFilterable, columnsSortable, columnsHidable } = useProps();
163162
const columnPreview = new ColumnPreview(column, 0);
164163
const caption = columnPreview.header;
165164
const canSort = columnsSortable && columnPreview.canSort;
@@ -174,9 +173,6 @@ function ColumnHeader({ column }: { column: ColumnsPreviewType }): ReactNode {
174173
>
175174
<div className="column-container">
176175
<div className="column-header">
177-
{columnsDraggable && columnPreview.canDrag && (
178-
<DragHandle draggable={false} onDragStart={() => {}} onDragEnd={() => {}} />
179-
)}
180176
<span>{caption.length > 0 ? caption : "\u00a0"}</span>
181177
{canSort && <FaArrowsAltV />}
182178
</div>

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

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,54 @@
11
import classNames from "classnames";
22
import { ReactElement } from "react";
33
import { ColumnHeader } from "./ColumnHeader";
4-
import { useColumn, useColumnsStore, useDatagridConfig, useHeaderDragnDropVM } from "../model/hooks/injection-hooks";
4+
import { useColumn, useColumnsStore, useDatagridConfig, useHeaderDndVM } from "../model/hooks/injection-hooks";
55
import { ColumnResizerProps } from "./ColumnResizer";
66
import { observer } from "mobx-react-lite";
7-
import { DragHandle } from "./DragHandle";
7+
import { useSortable } from "@dnd-kit/sortable";
88

99
export interface ColumnContainerProps {
1010
isLast?: boolean;
1111
resizer: ReactElement<ColumnResizerProps>;
1212
}
1313

1414
export const ColumnContainer = observer(function ColumnContainer(props: ColumnContainerProps): ReactElement {
15-
const { columnsFilterable, id: gridId } = useDatagridConfig();
16-
const { columnFilters } = useColumnsStore();
15+
const { columnsFilterable, columnsResizable, columnsSortable, id: gridId } = useDatagridConfig();
16+
const columnsStore = useColumnsStore();
17+
const { columnFilters } = columnsStore;
1718
const column = useColumn();
1819
const { canSort, columnId, columnIndex, canResize, sortDir, header } = column;
19-
const vm = useHeaderDragnDropVM();
20+
const isSortable = columnsSortable && canSort;
21+
const isResizable = columnsResizable && canResize;
2022
const caption = header.trim();
23+
const vm = useHeaderDndVM();
24+
const { setNodeRef, transform, transition, isDragging } = useSortable({
25+
id: columnId
26+
});
27+
const style = vm.getHeaderCellStyle(columnId, { transform, transition });
28+
const isLocked = !column.canDrag;
2129

2230
return (
2331
<div
24-
aria-sort={getAriaSort(canSort, sortDir)}
32+
aria-sort={getAriaSort(isSortable, sortDir)}
2533
className={classNames("th", {
26-
[`drop-${vm.dropTarget?.[1]}`]: columnId === vm.dropTarget?.[0],
27-
dragging: columnId === vm.dragging?.[1],
28-
"dragging-over-self": columnId === vm.dragging?.[1] && !vm.dropTarget
34+
"dragging-over-self": isDragging,
35+
"locked-drag-active": isLocked && vm.isDragging
2936
})}
3037
role="columnheader"
31-
style={!canSort ? { cursor: "unset" } : undefined}
38+
style={style}
3239
title={caption}
40+
ref={setNodeRef}
3341
data-column-id={columnId}
34-
onDrop={vm.isDraggable ? vm.handleOnDrop : undefined}
35-
onDragEnter={vm.isDraggable ? vm.handleDragEnter : undefined}
36-
onDragOver={vm.isDraggable ? vm.handleDragOver : undefined}
3742
>
38-
{vm.isDraggable && (
39-
<DragHandle draggable={vm.isDraggable} onDragStart={vm.handleDragStart} onDragEnd={vm.handleDragEnd} />
40-
)}
4143
<div className={classNames("column-container")} id={`${gridId}-column${columnId}`}>
4244
<ColumnHeader />
4345
{columnsFilterable && (
44-
<div className="filter" style={{ pointerEvents: vm.dragging ? "none" : undefined }}>
46+
<div className="filter" style={{ pointerEvents: vm.isDragging ? "none" : undefined }}>
4547
{columnFilters[columnIndex]?.renderFilterWidgets()}
4648
</div>
4749
)}
4850
</div>
49-
{canResize ? props.resizer : null}
51+
{isResizable ? props.resizer : null}
5052
</div>
5153
);
5254
});

0 commit comments

Comments
 (0)