playbook_ui 15.5.0.pre.alpha.draggableask12815 → 15.5.0.pre.alpha.draggablefix12557

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +6 -96
  3. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props.html.erb +1 -1
  4. data/app/pb_kits/playbook/pb_background/_background.tsx +6 -6
  5. data/app/pb_kits/playbook/pb_background/background.test.js +1 -5
  6. data/app/pb_kits/playbook/pb_background/docs/_background_light.html.erb +1 -1
  7. data/app/pb_kits/playbook/pb_background/docs/_background_light.jsx +1 -0
  8. data/app/pb_kits/playbook/pb_background/docs/example.yml +2 -2
  9. data/app/pb_kits/playbook/pb_bar_graph/BarGraphStyles.scss +58 -0
  10. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_compound_components.html.erb +0 -31
  11. data/app/pb_kits/playbook/pb_draggable/context/index.tsx +56 -233
  12. data/app/pb_kits/playbook/pb_draggable/context/types.ts +2 -4
  13. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_multiple_containers_dropzone.jsx +0 -1
  14. data/app/pb_kits/playbook/pb_draggable/docs/example.yml +3 -3
  15. data/app/pb_kits/playbook/pb_draggable/draggable.test.jsx +1 -77
  16. data/app/pb_kits/playbook/pb_file_upload/_file_upload.scss +4 -4
  17. data/app/pb_kits/playbook/pb_home_address_street/_home_address_street.tsx +22 -34
  18. data/app/pb_kits/playbook/pb_home_address_street/city_emphasis.html.erb +12 -16
  19. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_default.html.erb +1 -1
  20. data/app/pb_kits/playbook/pb_home_address_street/none_emphasis.html.erb +12 -16
  21. data/app/pb_kits/playbook/pb_home_address_street/street_emphasis.html.erb +12 -16
  22. data/app/pb_kits/playbook/pb_multiple_users/_multiple_users.scss +0 -10
  23. data/app/pb_kits/playbook/pb_multiple_users/_multiple_users.tsx +15 -66
  24. data/app/pb_kits/playbook/pb_multiple_users/docs/example.yml +0 -1
  25. data/app/pb_kits/playbook/pb_multiple_users/docs/index.js +0 -1
  26. data/app/pb_kits/playbook/pb_multiple_users/multiple_users.test.js +0 -25
  27. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +10 -44
  28. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_validation.html.erb +4 -34
  29. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_validation.jsx +7 -16
  30. data/app/pb_kits/playbook/pb_table/styles/_vertical_border.scss +0 -49
  31. data/app/pb_kits/playbook/pb_typeahead/_typeahead.test.jsx +0 -15
  32. data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +0 -3
  33. data/app/pb_kits/playbook/pb_typeahead/components/ClearIndicator.tsx +2 -13
  34. data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.tsx +1 -6
  35. data/app/pb_kits/playbook/pb_typeahead/components/ValueContainer.tsx +7 -34
  36. data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +0 -2
  37. data/app/pb_kits/playbook/pb_typeahead/docs/index.js +1 -2
  38. data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +1 -6
  39. data/dist/chunks/_typeahead-LoB4DX1N.js +6 -0
  40. data/dist/chunks/vendor.js +2 -2
  41. data/dist/playbook-rails-react-bindings.js +1 -1
  42. data/dist/playbook-rails.js +1 -1
  43. data/dist/playbook.css +1 -1
  44. data/lib/playbook/version.rb +1 -1
  45. metadata +4 -10
  46. data/app/pb_kits/playbook/pb_background/docs/_background_light.md +0 -1
  47. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_multiple_containers_dropzone.md +0 -22
  48. data/app/pb_kits/playbook/pb_multiple_users/docs/_multiple_users_with_tooltip.jsx +0 -42
  49. data/app/pb_kits/playbook/pb_multiple_users/docs/_multiple_users_with_tooltip.md +0 -1
  50. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_input_display.html.erb +0 -30
  51. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_input_display.jsx +0 -37
  52. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_input_display.md +0 -3
  53. data/dist/chunks/_typeahead-Dt3l7Dj8.js +0 -6
@@ -1,4 +1,4 @@
1
- import React, { createContext, useReducer, useContext, useEffect, useMemo, useRef } from "react";
1
+ import React, { createContext, useReducer, useContext, useEffect, useMemo } from "react";
2
2
  import { InitialStateType, ActionType, DraggableProviderType } from "./types";
3
3
 
4
4
  const initialState: InitialStateType = {
@@ -39,61 +39,46 @@ 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": {
42
+ case 'REORDER_ITEMS_CROSS_CONTAINER': {
45
43
  const { dragId, targetId, newContainer } = action.payload;
46
44
  const newItems = [...state.items];
47
- const draggedItem = newItems.find((item) => item && item.id === dragId);
48
-
49
- if (!draggedItem) return state;
50
-
45
+ const draggedItem = newItems.find(item => item.id === dragId);
51
46
  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;
47
+ const targetIndex = newItems.findIndex(item => item.id === targetId);
57
48
 
49
+ // Update container temporarily so dropzone preview works correctly
58
50
  const updatedItem = { ...draggedItem, container: newContainer };
51
+
59
52
  newItems.splice(draggedIndex, 1);
60
53
  newItems.splice(targetIndex, 0, updatedItem);
61
54
 
62
55
  return { ...state, items: newItems };
63
56
  }
64
-
65
- // Used only when enableCrossContainerPreview is true
66
- case "MOVE_TO_CONTAINER_END": {
57
+ case 'MOVE_TO_CONTAINER_END': {
67
58
  const { dragId, newContainer } = action.payload;
68
59
  const newItems = [...state.items];
69
- const draggedItem = newItems.find((item) => item && item.id === dragId);
70
-
71
- if (!draggedItem) return state;
72
-
60
+ const draggedItem = newItems.find(item => item.id === dragId);
73
61
  const draggedIndex = newItems.indexOf(draggedItem);
74
- if (draggedIndex === -1) return state;
75
62
 
63
+ // Update container temporarily so dropzone preview works correctly
76
64
  const updatedItem = { ...draggedItem, container: newContainer };
77
65
 
78
66
  // Remove from current position
79
67
  newItems.splice(draggedIndex, 1);
80
68
 
81
- // Insert at end of target container
82
- const lastIndexInContainer = newItems
83
- .map((item) => item && item.container)
84
- .lastIndexOf(newContainer);
85
-
69
+ // Find the last item in the target container and insert after it
70
+ const lastIndexInContainer = newItems.map(item => item.container).lastIndexOf(newContainer);
86
71
  if (lastIndexInContainer === -1) {
72
+ // Container is empty, add to end
87
73
  newItems.push(updatedItem);
88
74
  } else {
75
+ // Insert after last item in container
89
76
  newItems.splice(lastIndexInContainer + 1, 0, updatedItem);
90
77
  }
91
78
 
92
79
  return { ...state, items: newItems };
93
80
  }
94
-
95
- // Reset item back to its original container (e.g., when drag ends without valid drop)
96
- case "RESET_DRAG_CONTAINER": {
81
+ case 'RESET_DRAG_CONTAINER': {
97
82
  const { itemId, originalContainer } = action.payload;
98
83
  return {
99
84
  ...state,
@@ -104,7 +89,6 @@ const reducer = (state: InitialStateType, action: ActionType) => {
104
89
  )
105
90
  };
106
91
  }
107
-
108
92
  default:
109
93
  return state;
110
94
  }
@@ -127,24 +111,9 @@ export const DraggableProvider = ({
127
111
  onDrop,
128
112
  onDragOver,
129
113
  dropZone = { type: 'ghost', color: 'neutral', direction: 'vertical' },
130
- providerId = 'default', // fallback provided for backward compatibility
131
- // Opt-in flag for cross-container preview
132
- enableCrossContainerPreview = false,
114
+ providerId = 'default', // fallback provided for backward compatibility, so this does not become a required prop
133
115
  }: DraggableProviderType) => {
134
116
  const [state, dispatch] = useReducer(reducer, initialState);
135
-
136
- // Track drag state for global listener
137
- const dragStateRef = useRef<{
138
- isDragging: boolean;
139
- draggedItemId: string;
140
- originalContainer: string;
141
- dropOccurred: boolean;
142
- }>({
143
- isDragging: false,
144
- draggedItemId: '',
145
- originalContainer: '',
146
- dropOccurred: false,
147
- });
148
117
 
149
118
  // Parse dropZone prop - handle both string format (backward compatibility) and object format
150
119
  let dropZoneType = 'ghost';
@@ -174,94 +143,7 @@ export const DraggableProvider = ({
174
143
  onReorder(state.items);
175
144
  }, [state.items]);
176
145
 
177
- // Monitor for failed drops by detecting mouse/pointer release during drag (this is needed for cross container preview)
178
- useEffect(() => {
179
- if (!enableCrossContainerPreview) return;
180
-
181
- const handleGlobalMouseUp = () => {
182
- // If we're dragging and mouse is released, wait a bit to see if drop occurs
183
- if (dragStateRef.current.isDragging) {
184
- setTimeout(() => {
185
- // If drop still hasn't occurred, reset
186
- if (dragStateRef.current.isDragging && !dragStateRef.current.dropOccurred) {
187
- dispatch({
188
- type: 'RESET_DRAG_CONTAINER',
189
- payload: {
190
- itemId: dragStateRef.current.draggedItemId,
191
- originalContainer: dragStateRef.current.originalContainer,
192
- },
193
- });
194
- dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
195
- dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
196
- dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
197
-
198
- // Clear drag state
199
- dragStateRef.current = {
200
- isDragging: false,
201
- draggedItemId: '',
202
- originalContainer: '',
203
- dropOccurred: false,
204
- };
205
- }
206
- }, 50); // Small delay to let drop event fire if it's going to
207
- }
208
- };
209
-
210
- document.addEventListener('mouseup', handleGlobalMouseUp);
211
- document.addEventListener('pointerup', handleGlobalMouseUp);
212
-
213
- return () => {
214
- document.removeEventListener('mouseup', handleGlobalMouseUp);
215
- document.removeEventListener('pointerup', handleGlobalMouseUp);
216
- };
217
- }, [enableCrossContainerPreview]);
218
-
219
- // Detect when dragging stops (isDragging goes from truthy to empty)
220
- const prevIsDraggingRef = useRef(state.isDragging);
221
-
222
- useEffect(() => {
223
- if (!enableCrossContainerPreview) return;
224
-
225
- const wasDragging = prevIsDraggingRef.current;
226
- const isNowDragging = state.isDragging;
227
-
228
- // Drag just ended (was dragging, now not)
229
- if (wasDragging && !isNowDragging) {
230
-
231
- // If drop didn't occur, reset to original container
232
- if (!dragStateRef.current.dropOccurred && dragStateRef.current.draggedItemId) {
233
- dispatch({
234
- type: 'RESET_DRAG_CONTAINER',
235
- payload: {
236
- itemId: dragStateRef.current.draggedItemId,
237
- originalContainer: dragStateRef.current.originalContainer,
238
- },
239
- });
240
- }
241
-
242
- // Clear drag state
243
- dragStateRef.current = {
244
- isDragging: false,
245
- draggedItemId: '',
246
- originalContainer: '',
247
- dropOccurred: false,
248
- };
249
- }
250
-
251
- prevIsDraggingRef.current = isNowDragging;
252
- }, [state.isDragging, enableCrossContainerPreview]);
253
-
254
146
  const handleDragStart = (id: string, container: string) => {
255
- // Track drag in ref for global listener
256
- if (enableCrossContainerPreview) {
257
- dragStateRef.current = {
258
- isDragging: true,
259
- draggedItemId: id,
260
- originalContainer: container,
261
- dropOccurred: false,
262
- };
263
- }
264
-
265
147
  dispatch({ type: 'SET_DRAG_DATA', payload: { id: id, initialGroup: container, originId: providerId } });
266
148
  dispatch({ type: 'SET_IS_DRAGGING', payload: id });
267
149
  if (onDragStart) onDragStart(id, container);
@@ -271,42 +153,17 @@ export const DraggableProvider = ({
271
153
  if (state.dragData.originId !== providerId) return; // Ignore drag events from other providers
272
154
 
273
155
  if (state.dragData.id !== id) {
274
- if (enableCrossContainerPreview) {
275
- // Used only when enableCrossContainerPreview is true
276
- const draggedItem = state.items.find(
277
- (item) => item && item.id === state.dragData.id
278
- );
279
- const currentContainer =
280
- draggedItem && draggedItem.container
281
- ? draggedItem.container
282
- : state.dragData.initialGroup;
283
-
284
- const isCrossContainer =
285
- currentContainer !== container &&
286
- (currentContainer !== undefined || container !== undefined);
287
-
288
- if (isCrossContainer) {
289
- dispatch({
290
- type: "REORDER_ITEMS_CROSS_CONTAINER",
291
- payload: {
292
- dragId: state.dragData.id,
293
- targetId: id,
294
- newContainer: container,
295
- },
296
- });
297
- } else {
298
- // Same container: keep original behavior
299
- dispatch({
300
- type: "REORDER_ITEMS",
301
- payload: { dragId: state.dragData.id, targetId: id },
302
- });
303
- }
156
+ // Check if this is a cross-container drag
157
+ const isCrossContainer = state.dragData.initialGroup !== container;
158
+
159
+ if (isCrossContainer) {
160
+ // Use cross-container reorder to update container temporarily for dropzone preview
161
+ dispatch({ type: 'REORDER_ITEMS_CROSS_CONTAINER', payload: { dragId: state.dragData.id, targetId: id, newContainer: container } });
304
162
  } else {
305
- // Original behavior (no preview across containers)
306
- dispatch({type: "REORDER_ITEMS", payload: { dragId: state.dragData.id, targetId: id }});
163
+ // Same container: use normal reorder no need to be fancy nancy
164
+ dispatch({ type: 'REORDER_ITEMS', payload: { dragId: state.dragData.id, targetId: id } });
307
165
  }
308
-
309
- dispatch({type: "SET_DRAG_DATA",payload: {id: state.dragData.id, initialGroup: container, originId: providerId}});
166
+ dispatch({ type: 'SET_DRAG_DATA', payload: { id: state.dragData.id, initialGroup: container, originId: providerId } });
310
167
  }
311
168
  if (onDragEnter) onDragEnter(id, container);
312
169
  };
@@ -314,37 +171,21 @@ export const DraggableProvider = ({
314
171
  const handleDragEnd = () => {
315
172
  const draggedItemId = state.dragData.id;
316
173
  const originalContainer = state.dragData.initialGroup;
174
+ const draggedItem = state.items.find(item => item.id === draggedItemId);
175
+ const finalContainer = draggedItem ? draggedItem.container : originalContainer;
317
176
 
318
- // If enableCrossContainerPreview is true and no drop occurred, reset item to original container
319
- if (enableCrossContainerPreview && !dragStateRef.current.dropOccurred && draggedItemId && originalContainer) {
320
- dispatch({ type: 'RESET_DRAG_CONTAINER', payload: { itemId: draggedItemId, originalContainer } });
321
- }
177
+ // Find items above and below in the same container
178
+ const itemsInContainer = state.items.filter(item => item.container === finalContainer);
179
+ const indexInContainer = itemsInContainer.findIndex(item => item.id === draggedItemId);
180
+ const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
181
+ const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
322
182
 
323
183
  dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
324
184
  dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
325
185
  dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
326
186
 
327
- if (onDragEnd) {
328
- if (!enableCrossContainerPreview) {
329
- onDragEnd();
330
- } else {
331
- const draggedItem = state.items.find(item => item && item.id === draggedItemId);
332
- const finalContainer = draggedItem ? draggedItem.container : originalContainer;
333
-
334
- const itemsInContainer = state.items.filter(item => item && item.container === finalContainer);
335
- const indexInContainer = itemsInContainer.findIndex(item => item && item.id === draggedItemId);
336
- const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
337
- const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
338
-
339
- onDragEnd(
340
- draggedItemId,
341
- finalContainer,
342
- originalContainer,
343
- itemAbove,
344
- itemBelow
345
- );
346
- }
347
- }
187
+ // Pass enhanced info to onDragEnd callback to give dev more context
188
+ if (onDragEnd) onDragEnd(draggedItemId, finalContainer, originalContainer, itemAbove, itemBelow);
348
189
  };
349
190
 
350
191
  const changeCategory = (itemId: string, container: string) => {
@@ -356,36 +197,23 @@ export const DraggableProvider = ({
356
197
 
357
198
  const draggedItemId = state.dragData.id;
358
199
  const originalContainer = state.dragData.initialGroup;
200
+ const draggedItem = state.items.find(item => item.id === draggedItemId);
201
+
202
+ // Find items above and below in the same container (before changeCategory updates it)
203
+ const itemsInContainer = state.items.filter(item => item.container === container);
204
+ const indexInContainer = itemsInContainer.findIndex(item => item.id === draggedItemId);
205
+ const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
206
+ const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
359
207
 
360
- // Mark drop as successful in ref for global listener
361
- if (enableCrossContainerPreview) {
362
- dragStateRef.current.dropOccurred = true;
363
- }
364
-
365
208
  dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
366
209
  dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
367
- changeCategory(state.dragData.id, container);
368
- if (onDrop) {
369
- if (!enableCrossContainerPreview) {
370
- onDrop(container);
371
- } else {
372
- const draggedItem = state.items.find(item => item && item.id === draggedItemId);
373
- const updatedItem = draggedItem ? { ...draggedItem, container } : null;
374
-
375
- const itemsInContainer = state.items.filter(item => item && item.container === container);
376
- const indexInContainer = itemsInContainer.findIndex(item => item && item.id === draggedItemId);
377
- const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
378
- const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
379
-
380
- onDrop(
381
- draggedItemId,
382
- container,
383
- originalContainer,
384
- updatedItem,
385
- itemAbove,
386
- itemBelow
387
- );
388
- }
210
+ // changeCategory will ensure the container is set correctly on drop for cross container and same container drops
211
+ changeCategory(draggedItemId, container);
212
+
213
+ // Pass enhanced info to onDrop callback so devs have more context
214
+ if (onDrop && draggedItem) {
215
+ const updatedItem = { ...draggedItem, container };
216
+ onDrop(draggedItemId, container, originalContainer, updatedItem, itemAbove, itemBelow);
389
217
  }
390
218
  };
391
219
 
@@ -394,20 +222,15 @@ export const DraggableProvider = ({
394
222
 
395
223
  e.preventDefault();
396
224
  dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: container });
397
-
398
- if (enableCrossContainerPreview && state.dragData.id) {
399
- // Only when enableCrossContainerPreview is true: when hovering over a different container, move item to end
400
- const draggedItem = state.items.find(
401
- (item) => item && item.id === state.dragData.id
402
- );
403
- if (draggedItem && draggedItem.container !== container) {
404
- dispatch({
405
- type: "MOVE_TO_CONTAINER_END",
406
- payload: { dragId: state.dragData.id, newContainer: container },
407
- });
408
- }
225
+
226
+ // Check if we're dragging over a different container than where the item currently is
227
+ const draggedItem = state.items.find(item => item.id === state.dragData.id);
228
+ if (draggedItem && draggedItem.container !== container) {
229
+ // This handles the case when dragging to empty space at bottom of container OR in empty container
230
+ dispatch({ type: 'MOVE_TO_CONTAINER_END', payload: { dragId: state.dragData.id, newContainer: container } });
231
+ dispatch({ type: 'SET_DRAG_DATA', payload: { id: state.dragData.id, initialGroup: container, originId: providerId } });
409
232
  }
410
-
233
+
411
234
  if (onDragOver) onDragOver(e, container);
412
235
  };
413
236
 
@@ -431,4 +254,4 @@ export const DraggableProvider = ({
431
254
  return (
432
255
  <DragContext.Provider value={contextValue}>{children}</DragContext.Provider>
433
256
  );
434
- };
257
+ };
@@ -18,7 +18,6 @@ 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 }
22
21
  | { type: 'CHANGE_CATEGORY'; payload: { itemId: string; container: string } }
23
22
  | { type: 'REORDER_ITEMS'; payload: { dragId: string; targetId: string } }
24
23
  | { type: 'REORDER_ITEMS_CROSS_CONTAINER'; payload: { dragId: string; targetId: string; newContainer: string } }
@@ -37,10 +36,9 @@ export type ActionType =
37
36
  onReorder: (items: ItemType[]) => void;
38
37
  onDragStart?: (id: string, container: string) => void;
39
38
  onDragEnter?: (id: string, container: string) => void;
40
- onDragEnd?: (...args: any[]) => void;
41
- onDrop?: (...args: any[]) => void;
39
+ onDragEnd?: (draggedItemId: string, finalContainer: string, originalContainer: string, itemAbove: ItemType | null, itemBelow: ItemType | null) => void;
40
+ onDrop?: (draggedItemId: string, droppedContainer: string, originalContainer: string, item: ItemType, itemAbove: ItemType | null, itemBelow: ItemType | null) => void;
42
41
  onDragOver?: (e: Event, container: string) => void;
43
42
  dropZone?: DropZoneConfig | string; // Can accept string for backward compatibility
44
43
  providerId?: string;
45
- enableCrossContainerPreview?: boolean;
46
44
  }
@@ -83,7 +83,6 @@ const DraggableMultipleContainersDropzone = (props) => {
83
83
  return (
84
84
  <DraggableProvider
85
85
  dropZone={{type: "outline"}}
86
- enableCrossContainerPreview
87
86
  initialItems={data}
88
87
  onDragEnd={(draggedItemId, finalContainer, originalContainer, itemAbove, itemBelow) => {
89
88
  console.log(`Dragged Item ID: ${draggedItemId}`);
@@ -1,16 +1,16 @@
1
1
  examples:
2
2
  react:
3
3
  - draggable_default: Default
4
+ - draggable_multiple_containers_dropzone: Dragging Across Multiple Containers with Dropzones
4
5
  - draggable_with_list: Draggable with List Kit
5
6
  - draggable_with_selectable_list: Draggable with SelectableList Kit
6
7
  - draggable_with_cards: Draggable with Cards
7
8
  - draggable_with_table: Draggable with Table
9
+ - draggable_multiple_containers: Dragging Across Multiple Containers
8
10
  - draggable_drop_zones: Draggable Drop Zones
9
11
  - draggable_drop_zones_colors: Draggable Drop Zones Colors
10
12
  - draggable_drop_zones_line: Draggable Drop Zones Line
11
13
  - draggable_event_listeners: Draggable Event Listeners
12
- - draggable_multiple_containers: Dragging Across Multiple Containers
13
- - draggable_multiple_containers_dropzone: Dragging Across Multiple Containers with Dropzones
14
14
 
15
15
  rails:
16
16
  - draggable_default: Default
@@ -18,8 +18,8 @@ examples:
18
18
  - draggable_with_selectable_list: Draggable with SelectableList Kit
19
19
  - draggable_with_cards: Draggable with Cards
20
20
  - draggable_with_table: Draggable with Table
21
+ - draggable_multiple_containers: Dragging Across Multiple Containers
21
22
  - draggable_drop_zones: Draggable Drop Zones
22
23
  - draggable_drop_zones_colors: Draggable Drop Zones Colors
23
24
  - draggable_drop_zones_line: Draggable Drop Zones Line
24
25
  - draggable_event_listeners: Draggable Event Listeners
25
- - draggable_multiple_containers: Dragging Across Multiple Containers
@@ -255,80 +255,4 @@ test("line dropZone with horizontal direction applies 'line_horizontal' class to
255
255
  const container = kit.querySelector(".pb_draggable_container");
256
256
 
257
257
  expect(container).toHaveClass("line_horizontal");
258
- });
259
-
260
- // Cross-container drag tests
261
- const multiContainerData = [
262
- { id: "1", container: "To Do", text: "Task 1" },
263
- { id: "2", container: "To Do", text: "Task 2" },
264
- { id: "3", container: "In Progress", text: "Task 3" },
265
- { id: "4", container: "Done", text: "Task 4" },
266
- ];
267
-
268
- const containers = ["To Do", "In Progress", "Done"];
269
-
270
- const DraggableMultipleContainers = () => {
271
- const [initialState, setInitialState] = useState(multiContainerData);
272
-
273
- return (
274
- <div data-testid={testId}>
275
- <DraggableProvider
276
- dropZone={{ type: "outline" }}
277
- initialItems={multiContainerData}
278
- onReorder={(items) => setInitialState(items)}
279
- >
280
- {containers.map((container) => (
281
- <Draggable.Container
282
- container={container}
283
- data={{testid:`container-${container}`}}
284
- key={container}
285
- >
286
- {initialState
287
- .filter((item) => item.container === container)
288
- .map(({ id, text }) => (
289
- <Draggable.Item
290
- container={container}
291
- data-testid={`item-${id}`}
292
- dragId={id}
293
- key={id}
294
- >
295
- {text}
296
- </Draggable.Item>
297
- ))}
298
- </Draggable.Container>
299
- ))}
300
- </DraggableProvider>
301
- </div>
302
- );
303
- };
304
-
305
- test("renders multiple containers with correct items", () => {
306
- render(<DraggableMultipleContainers />);
307
-
308
- const kit = screen.getByTestId(testId);
309
- expect(kit).toBeInTheDocument();
310
-
311
- containers.forEach((container) => {
312
- const containerEl = kit.querySelector(`[data-testid="container-${container}"]`);
313
- expect(containerEl).toBeInTheDocument();
314
- });
315
-
316
- // Check items are in correct containers
317
- expect(screen.getByText("Task 1")).toBeInTheDocument();
318
- expect(screen.getByText("Task 2")).toBeInTheDocument();
319
- expect(screen.getByText("Task 3")).toBeInTheDocument();
320
- expect(screen.getByText("Task 4")).toBeInTheDocument();
321
- });
322
-
323
- test("items have correct container association", () => {
324
- const { container } = render(<DraggableMultipleContainers />);
325
-
326
- // items rendered within their respective containers
327
- const todoContainer = container.querySelector('[data-testid="container-To Do"]');
328
- const inProgressContainer = container.querySelector('[data-testid="container-In Progress"]');
329
- const doneContainer = container.querySelector('[data-testid="container-Done"]');
330
-
331
- expect(todoContainer.querySelectorAll('.pb_draggable_item')).toHaveLength(2);
332
- expect(inProgressContainer.querySelectorAll('.pb_draggable_item')).toHaveLength(1);
333
- expect(doneContainer.querySelectorAll('.pb_draggable_item')).toHaveLength(1);
334
- })
258
+ });
@@ -1,5 +1,5 @@
1
1
  .pb_file_upload_kit {
2
- .pb_card_kit {
2
+ .pb_card_kit_deselected_border_radius_md {
3
3
  border: 1px #ccc dashed;
4
4
  text-align: center;
5
5
  }
@@ -11,7 +11,7 @@
11
11
  }
12
12
  &.error,
13
13
  &.pb_file_upload_kit_error {
14
- .pb_card_kit {
14
+ .pb_card_kit_deselected_border_radius_md {
15
15
  border-color: $error;
16
16
  }
17
17
  .pb_body_kit_negative {
@@ -30,12 +30,12 @@
30
30
  }
31
31
 
32
32
  .dark .pb_file_upload_kit {
33
- .pb_card_kit {
33
+ .pb_card_kit_deselected_border_radius_md {
34
34
  border: 1px $text_dk_lighter dashed;
35
35
  }
36
36
  &.error,
37
37
  &.pb_file_upload_kit_error {
38
- .pb_card_kit {
38
+ .pb_card_kit_deselected_border_radius_md {
39
39
  border-color: $error_dark;
40
40
  }
41
41
  }
@@ -96,24 +96,20 @@ const HomeAddressStreet = (props: HomeAddressStreetProps): React.ReactElement =>
96
96
  {hasAllEmptyProps && '—'}
97
97
  {emphasis == 'street' && !hasAllEmptyProps &&
98
98
  <div>
99
- {(address || houseStyle) && (
100
- <Title
101
- className="pb_home_address_street_address"
102
- dark={dark}
103
- size={4}
104
- >
105
- {joinPresent([formatStreetAdr(address), houseStyle], ' · ')}
106
- </Title>
107
- )}
108
- {addressCont && (
109
- <Title
110
- className="pb_home_address_street_address"
111
- dark={dark}
112
- size={4}
113
- >
114
- {titleize(addressCont)}
115
- </Title>
116
- )}
99
+ <Title
100
+ className="pb_home_address_street_address"
101
+ dark={dark}
102
+ size={4}
103
+ >
104
+ {joinPresent([formatStreetAdr(address), houseStyle], ' · ')}
105
+ </Title>
106
+ <Title
107
+ className="pb_home_address_street_address"
108
+ dark={dark}
109
+ size={4}
110
+ >
111
+ {titleize(addressCont)}
112
+ </Title>
117
113
  <Body color="light">
118
114
  {`${city ? `${titleize(city)}, ` : ''}${uppercaseState}${zipcode ? ` ${zipcode}` : ''}`}
119
115
  </Body>
@@ -121,14 +117,10 @@ const HomeAddressStreet = (props: HomeAddressStreetProps): React.ReactElement =>
121
117
  }
122
118
  {emphasis == 'city' && !hasAllEmptyProps &&
123
119
  <div>
124
- {(address || houseStyle) && (
125
- <Body color="light">
126
- {joinPresent([formatStreetAdr(address), houseStyle], ' · ')}
127
- </Body>
128
- )}
129
- {addressCont && (
130
- <Body color="light">{titleize(addressCont)}</Body>
131
- )}
120
+ <Body color="light">
121
+ {joinPresent([formatStreetAdr(address), houseStyle], ' · ')}
122
+ </Body>
123
+ <Body color="light">{titleize(addressCont)}</Body>
132
124
  <div>
133
125
  <Title
134
126
  className="pb_home_address_street_address"
@@ -149,14 +141,10 @@ const HomeAddressStreet = (props: HomeAddressStreetProps): React.ReactElement =>
149
141
  }
150
142
  {emphasis == 'none' && !hasAllEmptyProps &&
151
143
  <div>
152
- {(address || houseStyle) && (
153
- <Body dark={dark}>
154
- {joinPresent([formatStreetAdr(address), houseStyle], ' · ')}
155
- </Body>
156
- )}
157
- {addressCont && (
158
- <Body dark={dark}>{formatStreetAdr(addressCont)}</Body>
159
- )}
144
+ <Body dark={dark}>
145
+ {joinPresent([formatStreetAdr(address), houseStyle], ' · ')}
146
+ </Body>
147
+ <Body dark={dark}>{formatStreetAdr(addressCont)}</Body>
160
148
  <div>
161
149
  <Body
162
150
  color="light"