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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2851c07d23768f59137cd7cb0ba34884e25960c1bc8700573a62c3aaa1004f83
4
- data.tar.gz: 74e6d86e0807f31e01ece7b7f3d620cea86367dfee7150493273543fb1ed682d
3
+ metadata.gz: 4c8379c2539757c4db1dcf2ed5c4a7562899728174921420d2e937f35a03f87d
4
+ data.tar.gz: 8bb8fd5264d9773fb4acecf09edca3c439945444c4e77c17e5a1745723c56fab
5
5
  SHA512:
6
- metadata.gz: a38283f21f3c2b2f2bb7132f27f6cf8fc161cd9f1fd3476f4521df857859c15960bd1e5b82857839d214b8c531adcf0082834eb6daf6a0fbc3df1ffb93b26d08
7
- data.tar.gz: 3e9aff80d60e0f20a4ce59810a631d167798f0abe3a3d54962b0ba66c9d9267dfc1bbcddbb3d9b6a03c66d3467cf1c6f0be574254344773b04b47359fc90a564
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
- <% column_definitions_two = [
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, so this does not become a required prop
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
- dispatch({ type: 'REORDER_ITEMS', payload: { dragId: state.dragData.id, targetId: id } });
107
- dispatch({ type: 'SET_DRAG_DATA', payload: { id: state.dragData.id, initialGroup: container, originId: providerId } });
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) 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) onDrop(container);
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?: (container: string) => void;
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
  }