playbook_ui 15.6.0.pre.rc.0 → 15.6.0.pre.rc.1
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/docs/_advanced_table_table_props.html.erb +1 -163
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props.jsx +0 -190
- data/app/pb_kits/playbook/pb_draggable/context/index.tsx +156 -6
- data/app/pb_kits/playbook/pb_draggable/context/types.ts +8 -3
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_multiple_containers_dropzone.jsx +180 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_multiple_containers_dropzone.md +22 -0
- data/app/pb_kits/playbook/pb_draggable/docs/example.yml +3 -2
- data/app/pb_kits/playbook/pb_draggable/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_draggable/draggable.test.jsx +77 -1
- data/dist/chunks/{_typeahead-kRdz5zPn.js → _typeahead-DUmTKJUc.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4c8379c2539757c4db1dcf2ed5c4a7562899728174921420d2e937f35a03f87d
|
|
4
|
+
data.tar.gz: 8bb8fd5264d9773fb4acecf09edca3c439945444c4e77c17e5a1745723c56fab
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4b72606b5b4b030ff3da899075efbb2215b864a6f9c8286de288ee86bc0084185aac17a7e12446c92f93899498c685df5876549e40f7be3b8210726479a656d6
|
|
7
|
+
data.tar.gz: ea1c0cee0bed7a7144fed0c139a754b2b8487b61e771d8b841f6d92723b7c1f2dff97a7e49177506c3cd55d9ef64aa2d8884f22481d002e518d954f0136c501b
|
|
@@ -29,167 +29,5 @@
|
|
|
29
29
|
label: "Graduated Students",
|
|
30
30
|
}
|
|
31
31
|
] %>
|
|
32
|
-
<%= pb_rails("caption", props: { text: "Advanced Table Vertical Border Table Props" }) %>
|
|
33
|
-
<%= pb_rails("advanced_table", props: { id: "table_props_table", table_data: @table_data, margin_bottom: "md", column_definitions: column_definitions, table_props: { vertical_border: true, container: false }}) %>
|
|
34
32
|
|
|
35
|
-
|
|
36
|
-
{
|
|
37
|
-
accessor: "year",
|
|
38
|
-
label: "Year",
|
|
39
|
-
cellAccessors: ["quarter", "month", "day"],
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
label: "Enrollment Data",
|
|
43
|
-
columns: [
|
|
44
|
-
{
|
|
45
|
-
accessor: "newEnrollments",
|
|
46
|
-
label: "New Enrollments",
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
accessor: "scheduledMeetings",
|
|
50
|
-
label: "Scheduled Meetings",
|
|
51
|
-
},
|
|
52
|
-
],
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
label: "Performance Data",
|
|
56
|
-
columns: [
|
|
57
|
-
{
|
|
58
|
-
accessor: "attendanceRate",
|
|
59
|
-
label: "Attendance Rate",
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
accessor: "completedClasses",
|
|
63
|
-
label: "Completed Classes",
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
accessor: "classCompletionRate",
|
|
67
|
-
label: "Class Completion Rate",
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
accessor: "graduatedStudents",
|
|
71
|
-
label: "Graduated Students",
|
|
72
|
-
},
|
|
73
|
-
],
|
|
74
|
-
},
|
|
75
|
-
] %>
|
|
76
|
-
<%= pb_rails("caption", props: { text: "Advanced Table Vertical Border Multi Header" }) %>
|
|
77
|
-
<%= pb_rails("advanced_table", props: { id: "table_multi_headers_vertical_borders", margin_bottom: "md", table_data: @table_data, column_definitions: column_definitions_two, table_props: { vertical_border: true } }) %>
|
|
78
|
-
|
|
79
|
-
<% column_definitions_three = [
|
|
80
|
-
{
|
|
81
|
-
accessor: "year",
|
|
82
|
-
label: "Year",
|
|
83
|
-
cellAccessors: ["quarter", "month", "day"],
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
label: "Enrollment Data",
|
|
87
|
-
columns: [
|
|
88
|
-
{
|
|
89
|
-
label: "Enrollment Stats",
|
|
90
|
-
columns: [
|
|
91
|
-
{
|
|
92
|
-
accessor: "newEnrollments",
|
|
93
|
-
label: "New Enrollments",
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
accessor: "scheduledMeetings",
|
|
97
|
-
label: "Scheduled Meetings",
|
|
98
|
-
},
|
|
99
|
-
],
|
|
100
|
-
},
|
|
101
|
-
],
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
label: "Performance Data",
|
|
105
|
-
columns: [
|
|
106
|
-
{
|
|
107
|
-
label: "Completion Metrics",
|
|
108
|
-
columns: [
|
|
109
|
-
{
|
|
110
|
-
accessor: "completedClasses",
|
|
111
|
-
label: "Completed Classes",
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
accessor: "classCompletionRate",
|
|
115
|
-
label: "Class Completion Rate",
|
|
116
|
-
},
|
|
117
|
-
],
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
label: "Attendance",
|
|
121
|
-
columns: [
|
|
122
|
-
{
|
|
123
|
-
accessor: "attendanceRate",
|
|
124
|
-
label: "Attendance Rate",
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
accessor: "scheduledMeetings",
|
|
128
|
-
label: "Scheduled Meetings",
|
|
129
|
-
},
|
|
130
|
-
],
|
|
131
|
-
},
|
|
132
|
-
],
|
|
133
|
-
},
|
|
134
|
-
] %>
|
|
135
|
-
<%= pb_rails("caption", props: { text: "Advanced Table Vertical Border Multi Header with Column Group Border Color" }) %>
|
|
136
|
-
<%= pb_rails("advanced_table", props: { id: "beta_table_with_color_headers", margin_bottom: "md", table_data: @table_data, column_definitions: column_definitions_three, column_group_border_color: "text_lt_default", table_props: { vertical_border: true } }) %>
|
|
137
|
-
|
|
138
|
-
<% column_definitions_four = [
|
|
139
|
-
{
|
|
140
|
-
accessor: "year",
|
|
141
|
-
label: "Year",
|
|
142
|
-
cellAccessors: ["quarter", "month", "day"],
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
label: "Enrollment Data",
|
|
146
|
-
columns: [
|
|
147
|
-
{
|
|
148
|
-
label: "Enrollment Stats",
|
|
149
|
-
columns: [
|
|
150
|
-
{
|
|
151
|
-
accessor: "newEnrollments",
|
|
152
|
-
label: "New Enrollments",
|
|
153
|
-
},
|
|
154
|
-
{
|
|
155
|
-
accessor: "scheduledMeetings",
|
|
156
|
-
label: "Scheduled Meetings",
|
|
157
|
-
},
|
|
158
|
-
],
|
|
159
|
-
},
|
|
160
|
-
],
|
|
161
|
-
},
|
|
162
|
-
{
|
|
163
|
-
label: "Performance Data",
|
|
164
|
-
columns: [
|
|
165
|
-
{
|
|
166
|
-
label: "Completion Metrics",
|
|
167
|
-
columns: [
|
|
168
|
-
{
|
|
169
|
-
accessor: "completedClasses",
|
|
170
|
-
label: "Completed Classes",
|
|
171
|
-
},
|
|
172
|
-
{
|
|
173
|
-
accessor: "classCompletionRate",
|
|
174
|
-
label: "Class Completion Rate",
|
|
175
|
-
},
|
|
176
|
-
],
|
|
177
|
-
},
|
|
178
|
-
{
|
|
179
|
-
label: "Attendance",
|
|
180
|
-
columns: [
|
|
181
|
-
{
|
|
182
|
-
accessor: "attendanceRate",
|
|
183
|
-
label: "Attendance Rate",
|
|
184
|
-
},
|
|
185
|
-
{
|
|
186
|
-
accessor: "scheduledMeetings",
|
|
187
|
-
label: "Scheduled Meetings",
|
|
188
|
-
},
|
|
189
|
-
],
|
|
190
|
-
},
|
|
191
|
-
],
|
|
192
|
-
},
|
|
193
|
-
] %>
|
|
194
|
-
<%= pb_rails("caption", props: { text: "Advanced Table Vertical Border Multi Header No Vertical Border" }) %>
|
|
195
|
-
<%= pb_rails("advanced_table", props: {id: "beta_table_with_muilti_headers", table_data: @table_data, column_definitions: column_definitions_four }) %>
|
|
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 }}) %>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from "react"
|
|
2
2
|
import AdvancedTable from '../../pb_advanced_table/_advanced_table'
|
|
3
3
|
import MOCK_DATA from "./advanced_table_mock_data.json"
|
|
4
|
-
import Caption from "../../pb_caption/_caption"
|
|
5
4
|
|
|
6
5
|
const AdvancedTableTableProps = (props) => {
|
|
7
6
|
const columnDefinitions = [
|
|
@@ -41,203 +40,14 @@ const AdvancedTableTableProps = (props) => {
|
|
|
41
40
|
verticalBorder: true
|
|
42
41
|
}
|
|
43
42
|
|
|
44
|
-
const columnDefinitionsTwo = [
|
|
45
|
-
{
|
|
46
|
-
accessor: "year",
|
|
47
|
-
label: "Year",
|
|
48
|
-
cellAccessors: ["quarter", "month", "day"],
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
label: "Enrollment Data",
|
|
52
|
-
columns: [
|
|
53
|
-
{
|
|
54
|
-
accessor: "newEnrollments",
|
|
55
|
-
label: "New Enrollments",
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
accessor: "scheduledMeetings",
|
|
59
|
-
label: "Scheduled Meetings",
|
|
60
|
-
},
|
|
61
|
-
],
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
label: "Performance Data",
|
|
65
|
-
columns: [
|
|
66
|
-
{
|
|
67
|
-
accessor: "attendanceRate",
|
|
68
|
-
label: "Attendance Rate",
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
accessor: "completedClasses",
|
|
72
|
-
label: "Completed Classes",
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
accessor: "classCompletionRate",
|
|
76
|
-
label: "Class Completion Rate",
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
accessor: "graduatedStudents",
|
|
80
|
-
label: "Graduated Students",
|
|
81
|
-
},
|
|
82
|
-
],
|
|
83
|
-
},
|
|
84
|
-
];
|
|
85
|
-
|
|
86
|
-
const tablePropsTwo = {
|
|
87
|
-
verticalBorder: true,
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const columnDefinitionsThree = [
|
|
91
|
-
{
|
|
92
|
-
accessor: "year",
|
|
93
|
-
label: "Year",
|
|
94
|
-
cellAccessors: ["quarter", "month", "day"],
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
label: "Enrollment Data",
|
|
98
|
-
columns: [
|
|
99
|
-
{
|
|
100
|
-
label: "Enrollment Stats",
|
|
101
|
-
columns: [
|
|
102
|
-
{
|
|
103
|
-
accessor: "newEnrollments",
|
|
104
|
-
label: "New Enrollments",
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
accessor: "scheduledMeetings",
|
|
108
|
-
label: "Scheduled Meetings",
|
|
109
|
-
},
|
|
110
|
-
],
|
|
111
|
-
},
|
|
112
|
-
],
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
label: "Performance Data",
|
|
116
|
-
columns: [
|
|
117
|
-
{
|
|
118
|
-
label: "Completion Metrics",
|
|
119
|
-
columns: [
|
|
120
|
-
{
|
|
121
|
-
accessor: "completedClasses",
|
|
122
|
-
label: "Completed Classes",
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
accessor: "classCompletionRate",
|
|
126
|
-
label: "Class Completion Rate",
|
|
127
|
-
},
|
|
128
|
-
],
|
|
129
|
-
},
|
|
130
|
-
{
|
|
131
|
-
label: "Attendance",
|
|
132
|
-
columns: [
|
|
133
|
-
{
|
|
134
|
-
accessor: "attendanceRate",
|
|
135
|
-
label: "Attendance Rate",
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
accessor: "scheduledMeetings",
|
|
139
|
-
label: "Scheduled Meetings",
|
|
140
|
-
},
|
|
141
|
-
],
|
|
142
|
-
},
|
|
143
|
-
],
|
|
144
|
-
},
|
|
145
|
-
];
|
|
146
|
-
|
|
147
|
-
const tablePropsThree = {
|
|
148
|
-
verticalBorder: true
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const columnDefinitionsFour = [
|
|
152
|
-
{
|
|
153
|
-
accessor: "year",
|
|
154
|
-
label: "Year",
|
|
155
|
-
cellAccessors: ["quarter", "month", "day"],
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
label: "Enrollment Data",
|
|
159
|
-
columns: [
|
|
160
|
-
{
|
|
161
|
-
label: "Enrollment Stats",
|
|
162
|
-
columns: [
|
|
163
|
-
{
|
|
164
|
-
accessor: "newEnrollments",
|
|
165
|
-
label: "New Enrollments",
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
accessor: "scheduledMeetings",
|
|
169
|
-
label: "Scheduled Meetings",
|
|
170
|
-
},
|
|
171
|
-
],
|
|
172
|
-
},
|
|
173
|
-
],
|
|
174
|
-
},
|
|
175
|
-
{
|
|
176
|
-
label: "Performance Data",
|
|
177
|
-
columns: [
|
|
178
|
-
{
|
|
179
|
-
label: "Completion Metrics",
|
|
180
|
-
columns: [
|
|
181
|
-
{
|
|
182
|
-
accessor: "completedClasses",
|
|
183
|
-
label: "Completed Classes",
|
|
184
|
-
},
|
|
185
|
-
{
|
|
186
|
-
accessor: "classCompletionRate",
|
|
187
|
-
label: "Class Completion Rate",
|
|
188
|
-
},
|
|
189
|
-
],
|
|
190
|
-
},
|
|
191
|
-
{
|
|
192
|
-
label: "Attendance",
|
|
193
|
-
columns: [
|
|
194
|
-
{
|
|
195
|
-
accessor: "attendanceRate",
|
|
196
|
-
label: "Attendance Rate",
|
|
197
|
-
},
|
|
198
|
-
{
|
|
199
|
-
accessor: "scheduledMeetings",
|
|
200
|
-
label: "Scheduled Meetings",
|
|
201
|
-
},
|
|
202
|
-
],
|
|
203
|
-
},
|
|
204
|
-
],
|
|
205
|
-
},
|
|
206
|
-
];
|
|
207
|
-
|
|
208
43
|
return (
|
|
209
44
|
<div>
|
|
210
|
-
<Caption text="Advanced Table Vertical Border Table Props" />
|
|
211
45
|
<AdvancedTable
|
|
212
46
|
columnDefinitions={columnDefinitions}
|
|
213
|
-
marginBottom="md"
|
|
214
47
|
tableData={MOCK_DATA}
|
|
215
48
|
tableProps={tableProps}
|
|
216
49
|
{...props}
|
|
217
50
|
/>
|
|
218
|
-
<Caption text="Advanced Table Vertical Border Multi Header" />
|
|
219
|
-
<AdvancedTable
|
|
220
|
-
columnDefinitions={columnDefinitionsTwo}
|
|
221
|
-
marginBottom="md"
|
|
222
|
-
tableData={MOCK_DATA}
|
|
223
|
-
tableProps={tablePropsTwo}
|
|
224
|
-
{...props}
|
|
225
|
-
/>
|
|
226
|
-
<Caption text="Advanced Table Vertical Border Multi Header with Column Group Border Color" />
|
|
227
|
-
<AdvancedTable
|
|
228
|
-
columnDefinitions={columnDefinitionsThree}
|
|
229
|
-
columnGroupBorderColor="text_lt_default"
|
|
230
|
-
marginBottom="md"
|
|
231
|
-
tableData={MOCK_DATA}
|
|
232
|
-
tableProps={tablePropsThree}
|
|
233
|
-
{...props}
|
|
234
|
-
/>
|
|
235
|
-
<Caption text="Advanced Table Vertical Border Multi Header No Vertical Border" />
|
|
236
|
-
<AdvancedTable
|
|
237
|
-
columnDefinitions={columnDefinitionsFour}
|
|
238
|
-
tableData={MOCK_DATA}
|
|
239
|
-
{...props}
|
|
240
|
-
/>
|
|
241
51
|
</div>
|
|
242
52
|
)
|
|
243
53
|
}
|
|
@@ -39,6 +39,59 @@ const reducer = (state: InitialStateType, action: ActionType) => {
|
|
|
39
39
|
|
|
40
40
|
return { ...state, items: newItems };
|
|
41
41
|
}
|
|
42
|
+
|
|
43
|
+
// Used only when enableCrossContainerPreview is true
|
|
44
|
+
case "REORDER_ITEMS_CROSS_CONTAINER": {
|
|
45
|
+
const { dragId, targetId, newContainer } = action.payload;
|
|
46
|
+
const newItems = [...state.items];
|
|
47
|
+
const draggedItem = newItems.find((item) => item && item.id === dragId);
|
|
48
|
+
|
|
49
|
+
if (!draggedItem) return state;
|
|
50
|
+
|
|
51
|
+
const draggedIndex = newItems.indexOf(draggedItem);
|
|
52
|
+
const targetIndex = newItems.findIndex(
|
|
53
|
+
(item) => item && item.id === targetId
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
if (draggedIndex === -1 || targetIndex === -1) return state;
|
|
57
|
+
|
|
58
|
+
const updatedItem = { ...draggedItem, container: newContainer };
|
|
59
|
+
newItems.splice(draggedIndex, 1);
|
|
60
|
+
newItems.splice(targetIndex, 0, updatedItem);
|
|
61
|
+
|
|
62
|
+
return { ...state, items: newItems };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Used only when enableCrossContainerPreview is true
|
|
66
|
+
case "MOVE_TO_CONTAINER_END": {
|
|
67
|
+
const { dragId, newContainer } = action.payload;
|
|
68
|
+
const newItems = [...state.items];
|
|
69
|
+
const draggedItem = newItems.find((item) => item && item.id === dragId);
|
|
70
|
+
|
|
71
|
+
if (!draggedItem) return state;
|
|
72
|
+
|
|
73
|
+
const draggedIndex = newItems.indexOf(draggedItem);
|
|
74
|
+
if (draggedIndex === -1) return state;
|
|
75
|
+
|
|
76
|
+
const updatedItem = { ...draggedItem, container: newContainer };
|
|
77
|
+
|
|
78
|
+
// Remove from current position
|
|
79
|
+
newItems.splice(draggedIndex, 1);
|
|
80
|
+
|
|
81
|
+
// Insert at end of target container
|
|
82
|
+
const lastIndexInContainer = newItems
|
|
83
|
+
.map((item) => item && item.container)
|
|
84
|
+
.lastIndexOf(newContainer);
|
|
85
|
+
|
|
86
|
+
if (lastIndexInContainer === -1) {
|
|
87
|
+
newItems.push(updatedItem);
|
|
88
|
+
} else {
|
|
89
|
+
newItems.splice(lastIndexInContainer + 1, 0, updatedItem);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return { ...state, items: newItems };
|
|
93
|
+
}
|
|
94
|
+
|
|
42
95
|
default:
|
|
43
96
|
return state;
|
|
44
97
|
}
|
|
@@ -61,7 +114,9 @@ export const DraggableProvider = ({
|
|
|
61
114
|
onDrop,
|
|
62
115
|
onDragOver,
|
|
63
116
|
dropZone = { type: 'ghost', color: 'neutral', direction: 'vertical' },
|
|
64
|
-
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,
|
|
65
120
|
}: DraggableProviderType) => {
|
|
66
121
|
const [state, dispatch] = useReducer(reducer, initialState);
|
|
67
122
|
|
|
@@ -103,17 +158,74 @@ export const DraggableProvider = ({
|
|
|
103
158
|
if (state.dragData.originId !== providerId) return; // Ignore drag events from other providers
|
|
104
159
|
|
|
105
160
|
if (state.dragData.id !== id) {
|
|
106
|
-
|
|
107
|
-
|
|
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
|
+
}
|
|
191
|
+
} else {
|
|
192
|
+
// Original behavior (no preview across containers)
|
|
193
|
+
dispatch({type: "REORDER_ITEMS", payload: { dragId: state.dragData.id, targetId: id }});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
dispatch({type: "SET_DRAG_DATA",payload: {id: state.dragData.id, initialGroup: container, originId: providerId}});
|
|
108
197
|
}
|
|
109
198
|
if (onDragEnter) onDragEnter(id, container);
|
|
110
199
|
};
|
|
111
200
|
|
|
112
201
|
const handleDragEnd = () => {
|
|
202
|
+
const draggedItemId = state.dragData.id;
|
|
203
|
+
const originalContainer = state.dragData.initialGroup;
|
|
204
|
+
|
|
113
205
|
dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
|
|
114
206
|
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
|
|
115
207
|
dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
|
|
116
|
-
if (onDragEnd)
|
|
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
|
+
}
|
|
117
229
|
};
|
|
118
230
|
|
|
119
231
|
const changeCategory = (itemId: string, container: string) => {
|
|
@@ -123,10 +235,34 @@ export const DraggableProvider = ({
|
|
|
123
235
|
const handleDrop = (container: string) => {
|
|
124
236
|
if (state.dragData.originId !== providerId) return; // Ignore drop events from other providers
|
|
125
237
|
|
|
238
|
+
const draggedItemId = state.dragData.id;
|
|
239
|
+
const originalContainer = state.dragData.initialGroup;
|
|
240
|
+
|
|
126
241
|
dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
|
|
127
242
|
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
|
|
128
243
|
changeCategory(state.dragData.id, container);
|
|
129
|
-
if (onDrop)
|
|
244
|
+
if (onDrop) {
|
|
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
|
+
}
|
|
265
|
+
}
|
|
130
266
|
};
|
|
131
267
|
|
|
132
268
|
const handleDragOver = (e: Event, container: string) => {
|
|
@@ -134,6 +270,20 @@ export const DraggableProvider = ({
|
|
|
134
270
|
|
|
135
271
|
e.preventDefault();
|
|
136
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
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
137
287
|
if (onDragOver) onDragOver(e, container);
|
|
138
288
|
};
|
|
139
289
|
|
|
@@ -157,4 +307,4 @@ export const DraggableProvider = ({
|
|
|
157
307
|
return (
|
|
158
308
|
<DragContext.Provider value={contextValue}>{children}</DragContext.Provider>
|
|
159
309
|
);
|
|
160
|
-
};
|
|
310
|
+
};
|
|
@@ -18,8 +18,12 @@ 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
|
-
| { type: 'REORDER_ITEMS'; payload: { dragId: string; targetId: string } }
|
|
23
|
+
| { type: 'REORDER_ITEMS'; payload: { dragId: string; targetId: string } }
|
|
24
|
+
| { type: 'REORDER_ITEMS_CROSS_CONTAINER'; payload: { dragId: string; targetId: string; newContainer: string } }
|
|
25
|
+
| { type: 'MOVE_TO_CONTAINER_END'; payload: { dragId: string; newContainer: string } }
|
|
26
|
+
| { type: 'RESET_DRAG_CONTAINER'; payload: { itemId: string; originalContainer: string } };
|
|
23
27
|
|
|
24
28
|
export interface DropZoneConfig {
|
|
25
29
|
type?: 'ghost' | 'outline' | 'shadow' | 'line';
|
|
@@ -33,9 +37,10 @@ export type ActionType =
|
|
|
33
37
|
onReorder: (items: ItemType[]) => void;
|
|
34
38
|
onDragStart?: (id: string, container: string) => void;
|
|
35
39
|
onDragEnter?: (id: string, container: string) => void;
|
|
36
|
-
onDragEnd?: () => void;
|
|
37
|
-
onDrop?: (
|
|
40
|
+
onDragEnd?: (...args: any[]) => void;
|
|
41
|
+
onDrop?: (...args: any[]) => void;
|
|
38
42
|
onDragOver?: (e: Event, container: string) => void;
|
|
39
43
|
dropZone?: DropZoneConfig | string; // Can accept string for backward compatibility
|
|
40
44
|
providerId?: string;
|
|
45
|
+
enableCrossContainerPreview?: boolean;
|
|
41
46
|
}
|