playbook_ui 15.5.0.pre.alpha.draggablefix12571 → 15.5.0.pre.alpha.draggablefix12589
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +96 -6
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props.html.erb +1 -1
- data/app/pb_kits/playbook/pb_draggable/context/index.tsx +122 -99
- data/app/pb_kits/playbook/pb_draggable/context/types.ts +4 -2
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_multiple_containers_dropzone.jsx +1 -0
- data/app/pb_kits/playbook/pb_table/styles/_vertical_border.scss +49 -0
- data/dist/chunks/{_typeahead-SD60YOim.js → _typeahead-DUmTKJUc.js} +2 -2
- data/dist/chunks/vendor.js +2 -2
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +3 -4
- data/app/pb_kits/playbook/pb_bar_graph/BarGraphStyles.scss +0 -58
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9048fda164619db498afb925949d4d2d56e2c273fcb753e7d43a504fe4c9e5a5
|
|
4
|
+
data.tar.gz: ff6ed156a4e852bcae45701f34feba01cdfa6f4e7a58b86181d76271781a5dd3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1bda0b34988a106ead207cc8fd705876f3550ebd6bc42c261da82f2be82a0f85fbe2398b9a345ce308840f052846be435f46a975a50e27fe7a4a939f3d27dacb
|
|
7
|
+
data.tar.gz: db28214d63307ebeae96aefbb6db9ad6376cd84ba3606d09deac5507a0c41c39146b3ca0fe23976551e95376d96d6de979e5428585dbde764594db0279827855
|
|
@@ -791,6 +791,28 @@
|
|
|
791
791
|
box-shadow: 1px 0px 0px 0px var(--column-border-color) !important;
|
|
792
792
|
}
|
|
793
793
|
|
|
794
|
+
// Override last-header-cell border color in dark mode
|
|
795
|
+
.pb_advanced_table_header {
|
|
796
|
+
> tr:not(:first-child) {
|
|
797
|
+
.last-header-cell {
|
|
798
|
+
border-right: 1px solid $border_dark !important;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
th[colspan]:not([colspan="1"]) {
|
|
803
|
+
border-right: 1px solid $border_dark !important;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
// Override last-cell border color in dark mode for body cells
|
|
808
|
+
.pb_advanced_table_body {
|
|
809
|
+
tr {
|
|
810
|
+
.last-cell:not(:last-of-type) {
|
|
811
|
+
border-right: 1px solid $border_dark !important;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
|
|
794
816
|
// Apply border colors in dark mode
|
|
795
817
|
&[class*="column-group-border-"] {
|
|
796
818
|
// For top-level column groups (ENROLLMENT DATA, PERFORMANCE DATA)
|
|
@@ -850,7 +872,7 @@
|
|
|
850
872
|
// Restore vertical border styling in dark mode when verticalBorder is true
|
|
851
873
|
.pb_table[data-vertical-border="true"] {
|
|
852
874
|
.pb_advanced_table_header {
|
|
853
|
-
> tr
|
|
875
|
+
> tr {
|
|
854
876
|
th:not(:last-child) {
|
|
855
877
|
border-right: 1px solid $border_dark !important;
|
|
856
878
|
}
|
|
@@ -864,11 +886,17 @@
|
|
|
864
886
|
}
|
|
865
887
|
}
|
|
866
888
|
|
|
889
|
+
tr.virtualized-table-row {
|
|
890
|
+
td:not(:last-child) {
|
|
891
|
+
border-right: 1px solid $border_dark !important;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
|
|
867
895
|
// When both verticalBorder AND columnGroupBorderColor are set in dark mode,
|
|
868
896
|
// override the default border-dark with the custom color
|
|
869
897
|
&.pb_advanced_table[class*="column-group-border-"] {
|
|
870
898
|
.pb_advanced_table_header {
|
|
871
|
-
> tr
|
|
899
|
+
> tr {
|
|
872
900
|
th:not(:last-child) {
|
|
873
901
|
border-right: 1px solid var(--column-border-color) !important;
|
|
874
902
|
}
|
|
@@ -881,6 +909,12 @@
|
|
|
881
909
|
border-right: 1px solid var(--column-border-color) !important;
|
|
882
910
|
}
|
|
883
911
|
}
|
|
912
|
+
|
|
913
|
+
tr.virtualized-table-row {
|
|
914
|
+
td:not(:last-child) {
|
|
915
|
+
border-right: 1px solid var(--column-border-color) !important;
|
|
916
|
+
}
|
|
917
|
+
}
|
|
884
918
|
}
|
|
885
919
|
}
|
|
886
920
|
|
|
@@ -985,34 +1019,90 @@
|
|
|
985
1019
|
// Firefox-specific fix for last-header-cell and last-cell vertical borders
|
|
986
1020
|
@-moz-document url-prefix() {
|
|
987
1021
|
.pb_advanced_table_header {
|
|
988
|
-
|
|
1022
|
+
th[colspan]:not([colspan="1"]):not(:last-child) {
|
|
1023
|
+
border-right: none !important;
|
|
1024
|
+
box-shadow: 1px 0 0 0 $border_light !important;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
.last-header-cell:not(:last-child),
|
|
1028
|
+
> tr:last-child .last-header-cell:not(:last-child) {
|
|
989
1029
|
border-right: none !important;
|
|
990
1030
|
box-shadow: 1px 0 0 0 $border_light !important;
|
|
991
1031
|
}
|
|
992
1032
|
}
|
|
993
1033
|
|
|
994
1034
|
.pb_advanced_table_body {
|
|
995
|
-
.last-cell:not(:last-
|
|
1035
|
+
tr .last-cell:not(:last-of-type),
|
|
1036
|
+
td.last-cell:not(:last-child),
|
|
1037
|
+
.pb_table_td.last-cell:not(:last-child) {
|
|
996
1038
|
border-right: none !important;
|
|
997
1039
|
box-shadow: 1px 0 0 0 $border_light !important;
|
|
998
1040
|
}
|
|
999
1041
|
}
|
|
1000
1042
|
|
|
1043
|
+
&[class*="column-group-border-"] {
|
|
1044
|
+
.pb_advanced_table_header {
|
|
1045
|
+
th[colspan]:not([colspan="1"]):not(:last-child),
|
|
1046
|
+
.last-header-cell:not(:last-child),
|
|
1047
|
+
> tr:last-child .last-header-cell:not(:last-child) {
|
|
1048
|
+
box-shadow: 1px 0 0 0 var(--column-border-color) !important;
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
.pb_advanced_table_body {
|
|
1053
|
+
tr .last-cell:not(:last-of-type),
|
|
1054
|
+
td.last-cell:not(:last-child),
|
|
1055
|
+
.pb_table_td.last-cell:not(:last-child) {
|
|
1056
|
+
box-shadow: 1px 0 0 0 var(--column-border-color) !important;
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1001
1061
|
// Dark mode Firefox fixes
|
|
1002
1062
|
&.dark {
|
|
1003
1063
|
.pb_advanced_table_header {
|
|
1004
|
-
|
|
1064
|
+
// Convert all colspan headers to box-shadow with dark color
|
|
1065
|
+
th[colspan]:not([colspan="1"]) {
|
|
1066
|
+
border-right: none !important;
|
|
1067
|
+
box-shadow: 1px 0 0 0 $border_dark !important;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
// Convert all last-header-cell borders to box-shadow with dark color
|
|
1071
|
+
.last-header-cell:not(:last-child),
|
|
1072
|
+
> tr:last-child .last-header-cell:not(:last-child),
|
|
1073
|
+
> tr:not(:first-child) .last-header-cell:not(:last-child),
|
|
1074
|
+
> tr:not(:first-child) .last-header-cell:last-child {
|
|
1005
1075
|
border-right: none !important;
|
|
1006
1076
|
box-shadow: 1px 0 0 0 $border_dark !important;
|
|
1007
1077
|
}
|
|
1008
1078
|
}
|
|
1009
1079
|
|
|
1010
1080
|
.pb_advanced_table_body {
|
|
1011
|
-
.last-cell:not(:last-
|
|
1081
|
+
tr .last-cell:not(:last-of-type),
|
|
1082
|
+
td.last-cell:not(:last-child),
|
|
1083
|
+
.pb_table_td.last-cell:not(:last-child) {
|
|
1012
1084
|
border-right: none !important;
|
|
1013
1085
|
box-shadow: 1px 0 0 0 $border_dark !important;
|
|
1014
1086
|
}
|
|
1015
1087
|
}
|
|
1088
|
+
|
|
1089
|
+
&[class*="column-group-border-"] {
|
|
1090
|
+
.pb_advanced_table_header {
|
|
1091
|
+
th[colspan]:not([colspan="1"]):not(:last-child),
|
|
1092
|
+
.last-header-cell:not(:last-child),
|
|
1093
|
+
> tr:last-child .last-header-cell:not(:last-child) {
|
|
1094
|
+
box-shadow: 1px 0 0 0 var(--column-border-color) !important;
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
.pb_advanced_table_body {
|
|
1099
|
+
tr .last-cell:not(:last-of-type),
|
|
1100
|
+
td.last-cell:not(:last-child),
|
|
1101
|
+
.pb_table_td.last-cell:not(:last-child) {
|
|
1102
|
+
box-shadow: 1px 0 0 0 var(--column-border-color) !important;
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1016
1106
|
}
|
|
1017
1107
|
}
|
|
1018
1108
|
}
|
|
@@ -30,4 +30,4 @@
|
|
|
30
30
|
}
|
|
31
31
|
] %>
|
|
32
32
|
|
|
33
|
-
<%= pb_rails("advanced_table", props: { id: "table_props_table", table_data: @table_data, column_definitions: column_definitions, table_props: { vertical_border: true, container: false }}) %>
|
|
33
|
+
<%= pb_rails("advanced_table", props: { id: "table_props_table", table_data: @table_data, column_definitions: column_definitions, table_props: { vertical_border: true, container: false }}) %>
|
|
@@ -30,65 +30,68 @@ const reducer = (state: InitialStateType, action: ActionType) => {
|
|
|
30
30
|
case 'REORDER_ITEMS': {
|
|
31
31
|
const { dragId, targetId } = action.payload;
|
|
32
32
|
const newItems = [...state.items];
|
|
33
|
-
const draggedItem = newItems.find(item => item
|
|
33
|
+
const draggedItem = newItems.find(item => item.id === dragId);
|
|
34
34
|
const draggedIndex = newItems.indexOf(draggedItem);
|
|
35
|
-
const targetIndex = newItems.findIndex(item => item
|
|
35
|
+
const targetIndex = newItems.findIndex(item => item.id === targetId);
|
|
36
36
|
|
|
37
37
|
newItems.splice(draggedIndex, 1);
|
|
38
38
|
newItems.splice(targetIndex, 0, draggedItem);
|
|
39
39
|
|
|
40
40
|
return { ...state, items: newItems };
|
|
41
41
|
}
|
|
42
|
-
|
|
42
|
+
|
|
43
|
+
// Used only when enableCrossContainerPreview is true
|
|
44
|
+
case "REORDER_ITEMS_CROSS_CONTAINER": {
|
|
43
45
|
const { dragId, targetId, newContainer } = action.payload;
|
|
44
46
|
const newItems = [...state.items];
|
|
45
|
-
const draggedItem = newItems.find(item => item && item.id === dragId);
|
|
47
|
+
const draggedItem = newItems.find((item) => item && item.id === dragId);
|
|
48
|
+
|
|
49
|
+
if (!draggedItem) return state;
|
|
50
|
+
|
|
46
51
|
const draggedIndex = newItems.indexOf(draggedItem);
|
|
47
|
-
const targetIndex = newItems.findIndex(
|
|
52
|
+
const targetIndex = newItems.findIndex(
|
|
53
|
+
(item) => item && item.id === targetId
|
|
54
|
+
);
|
|
48
55
|
|
|
49
|
-
|
|
50
|
-
const updatedItem = { ...draggedItem, container: newContainer };
|
|
56
|
+
if (draggedIndex === -1 || targetIndex === -1) return state;
|
|
51
57
|
|
|
58
|
+
const updatedItem = { ...draggedItem, container: newContainer };
|
|
52
59
|
newItems.splice(draggedIndex, 1);
|
|
53
60
|
newItems.splice(targetIndex, 0, updatedItem);
|
|
54
61
|
|
|
55
62
|
return { ...state, items: newItems };
|
|
56
63
|
}
|
|
57
|
-
|
|
64
|
+
|
|
65
|
+
// Used only when enableCrossContainerPreview is true
|
|
66
|
+
case "MOVE_TO_CONTAINER_END": {
|
|
58
67
|
const { dragId, newContainer } = action.payload;
|
|
59
68
|
const newItems = [...state.items];
|
|
60
|
-
const draggedItem = newItems.find(item => item && item.id === dragId);
|
|
69
|
+
const draggedItem = newItems.find((item) => item && item.id === dragId);
|
|
70
|
+
|
|
71
|
+
if (!draggedItem) return state;
|
|
72
|
+
|
|
61
73
|
const draggedIndex = newItems.indexOf(draggedItem);
|
|
74
|
+
if (draggedIndex === -1) return state;
|
|
62
75
|
|
|
63
|
-
// Update container temporarily so dropzone preview works correctly
|
|
64
76
|
const updatedItem = { ...draggedItem, container: newContainer };
|
|
65
77
|
|
|
66
78
|
// Remove from current position
|
|
67
79
|
newItems.splice(draggedIndex, 1);
|
|
68
80
|
|
|
69
|
-
//
|
|
70
|
-
const lastIndexInContainer = newItems
|
|
81
|
+
// Insert at end of target container
|
|
82
|
+
const lastIndexInContainer = newItems
|
|
83
|
+
.map((item) => item && item.container)
|
|
84
|
+
.lastIndexOf(newContainer);
|
|
85
|
+
|
|
71
86
|
if (lastIndexInContainer === -1) {
|
|
72
|
-
// Container is empty, add to end
|
|
73
87
|
newItems.push(updatedItem);
|
|
74
88
|
} else {
|
|
75
|
-
// Insert after last item in container
|
|
76
89
|
newItems.splice(lastIndexInContainer + 1, 0, updatedItem);
|
|
77
90
|
}
|
|
78
91
|
|
|
79
92
|
return { ...state, items: newItems };
|
|
80
93
|
}
|
|
81
|
-
|
|
82
|
-
const { itemId, originalContainer } = action.payload;
|
|
83
|
-
return {
|
|
84
|
-
...state,
|
|
85
|
-
items: state.items.map(item =>
|
|
86
|
-
item.id === itemId
|
|
87
|
-
? { ...item, container: originalContainer }
|
|
88
|
-
: item
|
|
89
|
-
)
|
|
90
|
-
};
|
|
91
|
-
}
|
|
94
|
+
|
|
92
95
|
default:
|
|
93
96
|
return state;
|
|
94
97
|
}
|
|
@@ -111,7 +114,9 @@ export const DraggableProvider = ({
|
|
|
111
114
|
onDrop,
|
|
112
115
|
onDragOver,
|
|
113
116
|
dropZone = { type: 'ghost', color: 'neutral', direction: 'vertical' },
|
|
114
|
-
providerId = 'default', // fallback provided for backward compatibility
|
|
117
|
+
providerId = 'default', // fallback provided for backward compatibility
|
|
118
|
+
// Opt-in flag for cross-container preview
|
|
119
|
+
enableCrossContainerPreview = false,
|
|
115
120
|
}: DraggableProviderType) => {
|
|
116
121
|
const [state, dispatch] = useReducer(reducer, initialState);
|
|
117
122
|
|
|
@@ -153,17 +158,42 @@ export const DraggableProvider = ({
|
|
|
153
158
|
if (state.dragData.originId !== providerId) return; // Ignore drag events from other providers
|
|
154
159
|
|
|
155
160
|
if (state.dragData.id !== id) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
161
|
+
if (enableCrossContainerPreview) {
|
|
162
|
+
// Used only when enableCrossContainerPreview is true
|
|
163
|
+
const draggedItem = state.items.find(
|
|
164
|
+
(item) => item && item.id === state.dragData.id
|
|
165
|
+
);
|
|
166
|
+
const currentContainer =
|
|
167
|
+
draggedItem && draggedItem.container
|
|
168
|
+
? draggedItem.container
|
|
169
|
+
: state.dragData.initialGroup;
|
|
170
|
+
|
|
171
|
+
const isCrossContainer =
|
|
172
|
+
currentContainer !== container &&
|
|
173
|
+
(currentContainer !== undefined || container !== undefined);
|
|
174
|
+
|
|
175
|
+
if (isCrossContainer) {
|
|
176
|
+
dispatch({
|
|
177
|
+
type: "REORDER_ITEMS_CROSS_CONTAINER",
|
|
178
|
+
payload: {
|
|
179
|
+
dragId: state.dragData.id,
|
|
180
|
+
targetId: id,
|
|
181
|
+
newContainer: container,
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
} else {
|
|
185
|
+
// Same container: keep original behavior
|
|
186
|
+
dispatch({
|
|
187
|
+
type: "REORDER_ITEMS",
|
|
188
|
+
payload: { dragId: state.dragData.id, targetId: id },
|
|
189
|
+
});
|
|
190
|
+
}
|
|
162
191
|
} else {
|
|
163
|
-
//
|
|
164
|
-
dispatch({
|
|
192
|
+
// Original behavior (no preview across containers)
|
|
193
|
+
dispatch({type: "REORDER_ITEMS", payload: { dragId: state.dragData.id, targetId: id }});
|
|
165
194
|
}
|
|
166
|
-
|
|
195
|
+
|
|
196
|
+
dispatch({type: "SET_DRAG_DATA",payload: {id: state.dragData.id, initialGroup: container, originId: providerId}});
|
|
167
197
|
}
|
|
168
198
|
if (onDragEnter) onDragEnter(id, container);
|
|
169
199
|
};
|
|
@@ -172,28 +202,30 @@ export const DraggableProvider = ({
|
|
|
172
202
|
const draggedItemId = state.dragData.id;
|
|
173
203
|
const originalContainer = state.dragData.initialGroup;
|
|
174
204
|
|
|
175
|
-
if (!draggedItemId) {
|
|
176
|
-
dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
|
|
177
|
-
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
|
|
178
|
-
dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const draggedItem = state.items.find(item => item && item.id === draggedItemId);
|
|
183
|
-
const finalContainer = draggedItem ? draggedItem.container : originalContainer;
|
|
184
|
-
|
|
185
|
-
// Find items above and below in the same container
|
|
186
|
-
const itemsInContainer = state.items.filter(item => item.container === finalContainer);
|
|
187
|
-
const indexInContainer = itemsInContainer.findIndex(item => item.id === draggedItemId);
|
|
188
|
-
const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
|
|
189
|
-
const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
|
|
190
|
-
|
|
191
205
|
dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
|
|
192
206
|
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
|
|
193
207
|
dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
208
|
+
if (onDragEnd) {
|
|
209
|
+
if (!enableCrossContainerPreview) {
|
|
210
|
+
onDragEnd();
|
|
211
|
+
} else {
|
|
212
|
+
const draggedItem = state.items.find(item => item && item.id === draggedItemId);
|
|
213
|
+
const finalContainer = draggedItem ? draggedItem.container : originalContainer;
|
|
214
|
+
|
|
215
|
+
const itemsInContainer = state.items.filter(item => item && item.container === finalContainer);
|
|
216
|
+
const indexInContainer = itemsInContainer.findIndex(item => item && item.id === draggedItemId);
|
|
217
|
+
const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
|
|
218
|
+
const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
|
|
219
|
+
|
|
220
|
+
onDragEnd(
|
|
221
|
+
draggedItemId,
|
|
222
|
+
finalContainer,
|
|
223
|
+
originalContainer,
|
|
224
|
+
itemAbove,
|
|
225
|
+
itemBelow
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
197
229
|
};
|
|
198
230
|
|
|
199
231
|
const changeCategory = (itemId: string, container: string) => {
|
|
@@ -205,34 +237,31 @@ export const DraggableProvider = ({
|
|
|
205
237
|
|
|
206
238
|
const draggedItemId = state.dragData.id;
|
|
207
239
|
const originalContainer = state.dragData.initialGroup;
|
|
208
|
-
|
|
209
|
-
if (!draggedItemId) return; // Guard against missing drag data when dropping too quickly
|
|
210
|
-
|
|
211
|
-
const draggedItem = state.items.find(item => item && item.id === draggedItemId);
|
|
212
|
-
|
|
213
|
-
if (!draggedItem) {
|
|
214
|
-
// Item not found in state - clear drag state and exit
|
|
215
|
-
dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
|
|
216
|
-
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
|
|
217
|
-
dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// Find items above and below in the same container (before changeCategory updates it)
|
|
222
|
-
const itemsInContainer = state.items.filter(item => item.container === container);
|
|
223
|
-
const indexInContainer = itemsInContainer.findIndex(item => item.id === draggedItemId);
|
|
224
|
-
const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
|
|
225
|
-
const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
|
|
226
|
-
|
|
240
|
+
|
|
227
241
|
dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
|
|
228
242
|
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
|
|
229
|
-
|
|
230
|
-
changeCategory(draggedItemId, container);
|
|
231
|
-
|
|
232
|
-
// Pass enhanced info to onDrop callback so devs have more context
|
|
243
|
+
changeCategory(state.dragData.id, container);
|
|
233
244
|
if (onDrop) {
|
|
234
|
-
|
|
235
|
-
|
|
245
|
+
if (!enableCrossContainerPreview) {
|
|
246
|
+
onDrop(container);
|
|
247
|
+
} else {
|
|
248
|
+
const draggedItem = state.items.find(item => item && item.id === draggedItemId);
|
|
249
|
+
const updatedItem = draggedItem ? { ...draggedItem, container } : null;
|
|
250
|
+
|
|
251
|
+
const itemsInContainer = state.items.filter(item => item && item.container === container);
|
|
252
|
+
const indexInContainer = itemsInContainer.findIndex(item => item && item.id === draggedItemId);
|
|
253
|
+
const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
|
|
254
|
+
const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
|
|
255
|
+
|
|
256
|
+
onDrop(
|
|
257
|
+
draggedItemId,
|
|
258
|
+
container,
|
|
259
|
+
originalContainer,
|
|
260
|
+
updatedItem,
|
|
261
|
+
itemAbove,
|
|
262
|
+
itemBelow
|
|
263
|
+
);
|
|
264
|
+
}
|
|
236
265
|
}
|
|
237
266
|
};
|
|
238
267
|
|
|
@@ -240,27 +269,21 @@ export const DraggableProvider = ({
|
|
|
240
269
|
if (state.dragData.originId !== providerId) return; // Ignore drag over events from other providers
|
|
241
270
|
|
|
242
271
|
e.preventDefault();
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
if (
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
// This handles the case when dragging to empty space at bottom of container OR in empty container
|
|
256
|
-
dispatch({ type: 'MOVE_TO_CONTAINER_END', payload: { dragId: state.dragData.id, newContainer: container } });
|
|
257
|
-
dispatch({ type: 'SET_DRAG_DATA', payload: { id: state.dragData.id, initialGroup: container, originId: providerId } });
|
|
272
|
+
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: container });
|
|
273
|
+
|
|
274
|
+
if (enableCrossContainerPreview && state.dragData.id) {
|
|
275
|
+
// Only when enableCrossContainerPreview is true: when hovering over a different container, move item to end
|
|
276
|
+
const draggedItem = state.items.find(
|
|
277
|
+
(item) => item && item.id === state.dragData.id
|
|
278
|
+
);
|
|
279
|
+
if (draggedItem && draggedItem.container !== container) {
|
|
280
|
+
dispatch({
|
|
281
|
+
type: "MOVE_TO_CONTAINER_END",
|
|
282
|
+
payload: { dragId: state.dragData.id, newContainer: container },
|
|
283
|
+
});
|
|
258
284
|
}
|
|
259
|
-
} else if (state.activeContainer !== container) {
|
|
260
|
-
// Just update active container if item is already in correct container
|
|
261
|
-
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: container });
|
|
262
285
|
}
|
|
263
|
-
|
|
286
|
+
|
|
264
287
|
if (onDragOver) onDragOver(e, container);
|
|
265
288
|
};
|
|
266
289
|
|
|
@@ -284,4 +307,4 @@ export const DraggableProvider = ({
|
|
|
284
307
|
return (
|
|
285
308
|
<DragContext.Provider value={contextValue}>{children}</DragContext.Provider>
|
|
286
309
|
);
|
|
287
|
-
};
|
|
310
|
+
};
|
|
@@ -18,6 +18,7 @@ export type ActionType =
|
|
|
18
18
|
} }
|
|
19
19
|
| { type: 'SET_IS_DRAGGING'; payload: string }
|
|
20
20
|
| { type: 'SET_ACTIVE_CONTAINER'; payload: string }
|
|
21
|
+
| { type: 'SET_CROSS_CONTAINER_PREVIEW'; payload: boolean }
|
|
21
22
|
| { type: 'CHANGE_CATEGORY'; payload: { itemId: string; container: string } }
|
|
22
23
|
| { type: 'REORDER_ITEMS'; payload: { dragId: string; targetId: string } }
|
|
23
24
|
| { type: 'REORDER_ITEMS_CROSS_CONTAINER'; payload: { dragId: string; targetId: string; newContainer: string } }
|
|
@@ -36,9 +37,10 @@ export type ActionType =
|
|
|
36
37
|
onReorder: (items: ItemType[]) => void;
|
|
37
38
|
onDragStart?: (id: string, container: string) => void;
|
|
38
39
|
onDragEnter?: (id: string, container: string) => void;
|
|
39
|
-
onDragEnd?: (
|
|
40
|
-
onDrop?: (
|
|
40
|
+
onDragEnd?: (...args: any[]) => void;
|
|
41
|
+
onDrop?: (...args: any[]) => void;
|
|
41
42
|
onDragOver?: (e: Event, container: string) => void;
|
|
42
43
|
dropZone?: DropZoneConfig | string; // Can accept string for backward compatibility
|
|
43
44
|
providerId?: string;
|
|
45
|
+
enableCrossContainerPreview?: boolean;
|
|
44
46
|
}
|
|
@@ -83,6 +83,7 @@ const DraggableMultipleContainersDropzone = (props) => {
|
|
|
83
83
|
return (
|
|
84
84
|
<DraggableProvider
|
|
85
85
|
dropZone={{type: "outline"}}
|
|
86
|
+
enableCrossContainerPreview
|
|
86
87
|
initialItems={data}
|
|
87
88
|
onDragEnd={(draggedItemId, finalContainer, originalContainer, itemAbove, itemBelow) => {
|
|
88
89
|
console.log(`Dragged Item ID: ${draggedItemId}`);
|
|
@@ -8,6 +8,25 @@
|
|
|
8
8
|
border-right: 1px solid $border_light !important;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
// **Advanced Table** specific rules to eliminate double borders when vertical-border is active
|
|
12
|
+
.pb_advanced_table &,
|
|
13
|
+
&[data-vertical-border="true"] {
|
|
14
|
+
// Remove first column box-shadow (preserve border-right in Chrome and use CSS var to respect column group border colors)
|
|
15
|
+
.table-header-cells:first-child,
|
|
16
|
+
.table-header-cells-custom:first-child,
|
|
17
|
+
td:first-child,
|
|
18
|
+
.pb_table_td:first-child,
|
|
19
|
+
.checkbox-cell.checkbox-cell-header:first-child {
|
|
20
|
+
box-shadow: none !important;
|
|
21
|
+
border-right: 1px solid var(--column-border-color, #{$border_light}) !important;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.pb_table_td:nth-child(2) {
|
|
25
|
+
box-shadow: none !important;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// --- End Advanced Table First Column Code Section ---
|
|
29
|
+
|
|
11
30
|
@media screen and (min-width: $screen-xs-min) {
|
|
12
31
|
tr:hover, .pb_table_tr:hover {
|
|
13
32
|
td:last-child, .pb_table_td:last-child {
|
|
@@ -63,5 +82,35 @@
|
|
|
63
82
|
}
|
|
64
83
|
}
|
|
65
84
|
}
|
|
85
|
+
|
|
86
|
+
// Dark mode support for advanced tables
|
|
87
|
+
.pb_advanced_table.dark & {
|
|
88
|
+
td, th, .pb_table_td, .pb_table_th {
|
|
89
|
+
border-right: 1px solid $border_dark !important;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
thead tr th {
|
|
93
|
+
border-right: 1px solid $border_dark !important;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
&[data-vertical-border="true"] {
|
|
97
|
+
.table-header-cells:first-child,
|
|
98
|
+
.table-header-cells-custom:first-child,
|
|
99
|
+
td:first-child,
|
|
100
|
+
.pb_table_td:first-child,
|
|
101
|
+
.checkbox-cell.checkbox-cell-header:first-child {
|
|
102
|
+
border-right: 1px solid var(--column-border-color, #{$border_dark}) !important;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@media screen and (min-width: $screen-xs-min) {
|
|
107
|
+
tr:hover, .pb_table_tr:hover {
|
|
108
|
+
td:last-child, .pb_table_td:last-child {
|
|
109
|
+
border-right-color: darken($border_dark, 10%) !important;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// --- End Advanced Table Dark Mode Code Section ---
|
|
66
115
|
}
|
|
67
116
|
}
|