playbook_ui 15.6.0.pre.alpha.draggableask12898 → 15.6.0.pre.alpha.play2552collapsibleiconrefactor12903

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: a1dcc4b2b7843d520c80b11f73c74e196883d2bd1a3ecf55d92c16be884d0099
4
- data.tar.gz: f071a4758c69143994205e7f230baa51f860f304d27887211d39eb910480b080
3
+ metadata.gz: b56117c9b815041948a7dc894ebad0caebf095ff1da7801e06ed7fec18da7eeb
4
+ data.tar.gz: 8e9f82470ea23ae8863567c8df94451dd927cdcbbaa7cf9d174a5fcd2ee627b7
5
5
  SHA512:
6
- metadata.gz: eab9a32c8a93c485adea409dca924d0d6947d00433ed2f2b347a820b102e71de3a015b2f00a09d11a6928eda21f68cb95131463946346ae2b86e8f941dc1cd96
7
- data.tar.gz: 3e2dc18bf9ad106c8dd35ce73ef90498e79eecfc1de411c4889c235d80e5aa0220013f49fcf12fdd9d09dd4738ba74f5410ade65eb4d913f764fc349dcce01d7
6
+ metadata.gz: 58c7104cca8322ba83b49875a68bc2a0a49ed6334337bf4a0e00bfa6d8c062bc45b8aadbe2644592a9dc358348cd972b47fef79efb89fbf32135c2f345f6bbd0
7
+ data.tar.gz: 1c1933805f799e9aeca540a29d3ac0861de4c8c8900ecfb62c7e1ea5eb1800e0df5d7dd4164afffb92788d84d19ed486921d7a572afcf4cf5823c5eeb64d5784
@@ -25,11 +25,11 @@ exports[`html structure is correct 1`] = `
25
25
  >
26
26
  <div
27
27
  class="icon_wrapper"
28
- style="vertical-align: middle; color: rgb(193, 205, 214);"
28
+ style="vertical-align: middle;"
29
29
  >
30
30
  <svg
31
31
  aria-label="chevron-down icon"
32
- class="pb_custom_icon svg-inline--fa svg_lg svg_fw"
32
+ class="pb_custom_icon svg-inline--fa color_text_lt_lighter svg_lg svg_fw"
33
33
  color="currentColor"
34
34
  fill="none"
35
35
  height="auto"
@@ -27,12 +27,12 @@ type colorMap = {
27
27
  };
28
28
 
29
29
  const colorMap = {
30
- default: "#242B42",
31
- light: "#687887",
32
- lighter: "#C1CDD6",
33
- link: "#0056CF",
34
- error: "#FF2229",
35
- success: "#00CA74",
30
+ default:"text_lt_default",
31
+ light: "text_lt_light",
32
+ lighter: "text_lt_lighter",
33
+ link: "primary",
34
+ error: "error",
35
+ success: "text_dk_success_sm",
36
36
  };
37
37
 
38
38
  const CollapsibleIcon = ({
@@ -68,9 +68,10 @@ const CollapsibleIcon = ({
68
68
  className="icon_wrapper"
69
69
  key={icon ? showIcon(icon)[0] : "chevron-down"}
70
70
  onClick={(e) => handleIconClick(e)}
71
- style={{ verticalAlign: "middle", color: color }}
71
+ style={{ verticalAlign: "middle"}}
72
72
  >
73
73
  <Icon
74
+ color={color}
74
75
  icon={icon ? showIcon(icon)[0] : "chevron-down"}
75
76
  size={iconSize}
76
77
  />
@@ -80,9 +81,10 @@ const CollapsibleIcon = ({
80
81
  className="icon_wrapper"
81
82
  key={icon ? showIcon(icon)[1] : "chevron-up"}
82
83
  onClick={(e) => handleIconClick(e)}
83
- style={{ verticalAlign: "middle", color: color }}
84
+ style={{ verticalAlign: "middle" }}
84
85
  >
85
86
  <Icon
87
+ color={color}
86
88
  icon={icon ? showIcon(icon)[1] : "chevron-up"}
87
89
  size={iconSize}
88
90
  />
@@ -7,7 +7,6 @@ const CollapsibleIcons = (props) => {
7
7
  <>
8
8
  <Collapsible
9
9
  icon={['plus','minus']}
10
- iconColor='white'
11
10
  >
12
11
  <Collapsible.Main {...props}>
13
12
  <div>{'Main Section'}</div>
@@ -22,7 +22,6 @@ const CollapsibleState = (props) => {
22
22
  <Collapsible
23
23
  collapsed={isCollapsed}
24
24
  icon={["plus", "minus"]}
25
- iconColor='white'
26
25
  padding="none"
27
26
  >
28
27
  <Collapsible.Main padding="sm"
@@ -41,7 +40,6 @@ const CollapsibleState = (props) => {
41
40
  <Collapsible
42
41
  collapsed={isCollapsed}
43
42
  icon={["plus", "minus"]}
44
- iconColor='white'
45
43
  padding="none"
46
44
  >
47
45
  <Collapsible.Main padding="sm"
@@ -60,7 +58,6 @@ const CollapsibleState = (props) => {
60
58
  <Collapsible
61
59
  collapsed={isCollapsed}
62
60
  icon={["plus", "minus"]}
63
- iconColor='white'
64
61
  padding="none"
65
62
  >
66
63
  <Collapsible.Main padding="sm"
@@ -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 = {
@@ -92,19 +92,6 @@ const reducer = (state: InitialStateType, action: ActionType) => {
92
92
  return { ...state, items: newItems };
93
93
  }
94
94
 
95
- // Reset item back to its original container (e.g., when drag ends without valid drop)
96
- case "RESET_DRAG_CONTAINER": {
97
- const { itemId, originalContainer } = action.payload;
98
- return {
99
- ...state,
100
- items: state.items.map(item =>
101
- item.id === itemId
102
- ? { ...item, container: originalContainer }
103
- : item
104
- )
105
- };
106
- }
107
-
108
95
  default:
109
96
  return state;
110
97
  }
@@ -132,27 +119,6 @@ export const DraggableProvider = ({
132
119
  enableCrossContainerPreview = false,
133
120
  }: DraggableProviderType) => {
134
121
  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
- currentContainer: string;
142
- dropOccurred: boolean;
143
- }>({
144
- isDragging: false,
145
- draggedItemId: '',
146
- originalContainer: '',
147
- currentContainer: '',
148
- dropOccurred: false,
149
- });
150
-
151
- // Track current state for use in gated event listeners (avoid stale closures)
152
- const stateRef = useRef(state);
153
- useEffect(() => {
154
- stateRef.current = state;
155
- }, [state]);
156
122
 
157
123
  // Parse dropZone prop - handle both string format (backward compatibility) and object format
158
124
  let dropZoneType = 'ghost';
@@ -182,224 +148,7 @@ export const DraggableProvider = ({
182
148
  onReorder(state.items);
183
149
  }, [state.items]);
184
150
 
185
- // Monitor for failed drops by detecting mouse/pointer release during drag (this is needed for cross container preview)
186
- useEffect(() => {
187
- if (!enableCrossContainerPreview) return;
188
-
189
- // Allow drops anywhere on the document by preventing default dragover
190
- const handleGlobalDragOver = (e: DragEvent) => {
191
- if (dragStateRef.current.isDragging) {
192
- e.preventDefault();
193
- }
194
- };
195
-
196
- // Handle drops anywhere on the document (including non-container areas)
197
- const handleGlobalDrop = (e: DragEvent) => {
198
- if (!dragStateRef.current.isDragging) return;
199
-
200
- // If a container already handled the drop, don't process again
201
- if (dragStateRef.current.dropOccurred) return;
202
-
203
- e.preventDefault();
204
-
205
- const currentContainer = dragStateRef.current.currentContainer;
206
-
207
- // If item is in a different container than original, treat it as a successful drop
208
- if (currentContainer && currentContainer !== dragStateRef.current.originalContainer) {
209
-
210
- // Mark as dropped so other handlers know
211
- dragStateRef.current.dropOccurred = true;
212
-
213
- // Trigger onDrop callback with the current container
214
- if (onDrop) {
215
- const draggedItem = stateRef.current.items.find(item => item && item.id === dragStateRef.current.draggedItemId);
216
- const updatedItem = draggedItem ? { ...draggedItem, container: currentContainer } : null;
217
- const itemsInContainer = stateRef.current.items.filter(item => item && item.container === currentContainer);
218
- const indexInContainer = itemsInContainer.findIndex(item => item && item.id === dragStateRef.current.draggedItemId);
219
- const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
220
- const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
221
-
222
- onDrop(
223
- dragStateRef.current.draggedItemId,
224
- currentContainer,
225
- dragStateRef.current.originalContainer,
226
- updatedItem,
227
- itemAbove,
228
- itemBelow
229
- );
230
- }
231
-
232
- // Trigger onDragEnd callback
233
- if (onDragEnd) {
234
- const itemsInContainer = stateRef.current.items.filter(item => item && item.container === currentContainer);
235
- const indexInContainer = itemsInContainer.findIndex(item => item && item.id === dragStateRef.current.draggedItemId);
236
- const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
237
- const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
238
-
239
- onDragEnd(
240
- dragStateRef.current.draggedItemId,
241
- currentContainer,
242
- dragStateRef.current.originalContainer,
243
- itemAbove,
244
- itemBelow
245
- );
246
- }
247
-
248
- dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
249
- dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
250
- dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
251
- } else {
252
- // Reset to original container (item didn't move or dropped in invalid zone)
253
- const originalContainer = dragStateRef.current.originalContainer;
254
-
255
- dispatch({
256
- type: 'RESET_DRAG_CONTAINER',
257
- payload: {
258
- itemId: dragStateRef.current.draggedItemId,
259
- originalContainer: originalContainer,
260
- },
261
- });
262
-
263
- // Call onDrop with original container info
264
- if (onDrop) {
265
- const draggedItem = stateRef.current.items.find(item => item && item.id === dragStateRef.current.draggedItemId);
266
- const updatedItem = draggedItem ? { ...draggedItem, container: originalContainer } : null;
267
- const itemsInContainer = stateRef.current.items.filter(item => item && item.container === originalContainer);
268
- const indexInContainer = itemsInContainer.findIndex(item => item && item.id === dragStateRef.current.draggedItemId);
269
- const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
270
- const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
271
-
272
- onDrop(
273
- dragStateRef.current.draggedItemId,
274
- originalContainer,
275
- originalContainer,
276
- updatedItem,
277
- itemAbove,
278
- itemBelow
279
- );
280
- }
281
-
282
- dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
283
- dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
284
- dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
285
- }
286
- };
287
-
288
- const handleGlobalMouseUp = () => {
289
- // If we're dragging and mouse is released, wait a bit to see if drop occurs
290
- if (dragStateRef.current.isDragging) {
291
- setTimeout(() => {
292
- const currentContainer = dragStateRef.current.currentContainer;
293
-
294
- // If drop still hasn't occurred, check if item is in a different container
295
- if (dragStateRef.current.isDragging && !dragStateRef.current.dropOccurred) {
296
- // If item is in a different container than original, treat it as a successful drop
297
- if (currentContainer && currentContainer !== dragStateRef.current.originalContainer) {
298
- // Trigger onDrop callback with the current container
299
- if (onDrop) {
300
- const draggedItem = stateRef.current.items.find(item => item && item.id === dragStateRef.current.draggedItemId);
301
- const updatedItem = draggedItem ? { ...draggedItem, container: currentContainer } : null;
302
- const itemsInContainer = stateRef.current.items.filter(item => item && item.container === currentContainer);
303
- const indexInContainer = itemsInContainer.findIndex(item => item && item.id === dragStateRef.current.draggedItemId);
304
- const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
305
- const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
306
-
307
- onDrop(
308
- dragStateRef.current.draggedItemId,
309
- currentContainer,
310
- dragStateRef.current.originalContainer,
311
- updatedItem,
312
- itemAbove,
313
- itemBelow
314
- );
315
- }
316
- } else {
317
- dispatch({
318
- type: 'RESET_DRAG_CONTAINER',
319
- payload: {
320
- itemId: dragStateRef.current.draggedItemId,
321
- originalContainer: dragStateRef.current.originalContainer,
322
- },
323
- });
324
- }
325
- dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
326
- dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
327
- dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
328
-
329
- // Clear drag state
330
- dragStateRef.current = {
331
- isDragging: false,
332
- draggedItemId: '',
333
- originalContainer: '',
334
- currentContainer: '',
335
- dropOccurred: false,
336
- };
337
- }
338
- }, 50); // Small delay to let drop event fire if it's going to
339
- }
340
- };
341
-
342
- document.addEventListener('dragover', handleGlobalDragOver);
343
- document.addEventListener('drop', handleGlobalDrop);
344
- document.addEventListener('mouseup', handleGlobalMouseUp);
345
- document.addEventListener('pointerup', handleGlobalMouseUp);
346
-
347
- return () => {
348
- document.removeEventListener('dragover', handleGlobalDragOver);
349
- document.removeEventListener('drop', handleGlobalDrop);
350
- document.removeEventListener('mouseup', handleGlobalMouseUp);
351
- document.removeEventListener('pointerup', handleGlobalMouseUp);
352
- };
353
- }, [enableCrossContainerPreview]);
354
-
355
- // Detect when dragging stops (isDragging goes from truthy to empty)
356
- const prevIsDraggingRef = useRef(state.isDragging);
357
-
358
- useEffect(() => {
359
- if (!enableCrossContainerPreview) return;
360
-
361
- const wasDragging = prevIsDraggingRef.current;
362
- const isNowDragging = state.isDragging;
363
-
364
- // Drag just ended (was dragging, now not)
365
- if (wasDragging && !isNowDragging) {
366
-
367
- // If drop didn't occur, reset to original container
368
- if (!dragStateRef.current.dropOccurred && dragStateRef.current.draggedItemId) {
369
- dispatch({
370
- type: 'RESET_DRAG_CONTAINER',
371
- payload: {
372
- itemId: dragStateRef.current.draggedItemId,
373
- originalContainer: dragStateRef.current.originalContainer,
374
- },
375
- });
376
- }
377
-
378
- // Clear drag state
379
- dragStateRef.current = {
380
- isDragging: false,
381
- draggedItemId: '',
382
- originalContainer: '',
383
- currentContainer: '',
384
- dropOccurred: false,
385
- };
386
- }
387
-
388
- prevIsDraggingRef.current = isNowDragging;
389
- }, [state.isDragging, enableCrossContainerPreview]);
390
-
391
151
  const handleDragStart = (id: string, container: string) => {
392
- // Track drag in ref for global listener
393
- if (enableCrossContainerPreview) {
394
- dragStateRef.current = {
395
- isDragging: true,
396
- draggedItemId: id,
397
- originalContainer: container,
398
- currentContainer: container,
399
- dropOccurred: false,
400
- };
401
- }
402
-
403
152
  dispatch({ type: 'SET_DRAG_DATA', payload: { id: id, initialGroup: container, originId: providerId } });
404
153
  dispatch({ type: 'SET_IS_DRAGGING', payload: id });
405
154
  if (onDragStart) onDragStart(id, container);
@@ -432,10 +181,6 @@ export const DraggableProvider = ({
432
181
  newContainer: container,
433
182
  },
434
183
  });
435
- // Update current container in ref
436
- if (enableCrossContainerPreview) {
437
- dragStateRef.current.currentContainer = container;
438
- }
439
184
  } else {
440
185
  // Same container: keep original behavior
441
186
  dispatch({
@@ -448,10 +193,7 @@ export const DraggableProvider = ({
448
193
  dispatch({type: "REORDER_ITEMS", payload: { dragId: state.dragData.id, targetId: id }});
449
194
  }
450
195
 
451
- // When enableCrossContainerPreview is true, preserve the original initialGroup
452
- // Otherwise, update it to track the current container
453
- const newInitialGroup = enableCrossContainerPreview ? state.dragData.initialGroup : container;
454
- dispatch({type: "SET_DRAG_DATA",payload: {id: state.dragData.id, initialGroup: newInitialGroup, originId: providerId}});
196
+ dispatch({type: "SET_DRAG_DATA",payload: {id: state.dragData.id, initialGroup: container, originId: providerId}});
455
197
  }
456
198
  if (onDragEnter) onDragEnter(id, container);
457
199
  };
@@ -460,29 +202,17 @@ export const DraggableProvider = ({
460
202
  const draggedItemId = state.dragData.id;
461
203
  const originalContainer = state.dragData.initialGroup;
462
204
 
463
- // If enableCrossContainerPreview is true and no drop occurred, reset item to original container
464
- if (enableCrossContainerPreview && !dragStateRef.current.dropOccurred && draggedItemId && originalContainer) {
465
- dispatch({ type: 'RESET_DRAG_CONTAINER', payload: { itemId: draggedItemId, originalContainer } });
466
- }
467
-
468
205
  dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
469
206
  dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
470
207
  dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
471
-
472
- // Only call onDragEnd if drop didn't already occur (for enableCrossContainerPreview)
473
- // If drop occurred, handleDrop or global drop handler already called onDragEnd
474
- if (enableCrossContainerPreview && dragStateRef.current.dropOccurred) {
475
- return;
476
- }
477
-
478
208
  if (onDragEnd) {
479
209
  if (!enableCrossContainerPreview) {
480
210
  onDragEnd();
481
211
  } else {
482
- const draggedItem = stateRef.current.items.find(item => item && item.id === draggedItemId);
212
+ const draggedItem = state.items.find(item => item && item.id === draggedItemId);
483
213
  const finalContainer = draggedItem ? draggedItem.container : originalContainer;
484
214
 
485
- const itemsInContainer = stateRef.current.items.filter(item => item && item.container === finalContainer);
215
+ const itemsInContainer = state.items.filter(item => item && item.container === finalContainer);
486
216
  const indexInContainer = itemsInContainer.findIndex(item => item && item.id === draggedItemId);
487
217
  const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
488
218
  const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
@@ -507,58 +237,32 @@ export const DraggableProvider = ({
507
237
 
508
238
  const draggedItemId = state.dragData.id;
509
239
  const originalContainer = state.dragData.initialGroup;
510
-
511
- // Mark drop as successful in ref for global listener
512
- if (enableCrossContainerPreview) {
513
- dragStateRef.current.dropOccurred = true;
514
- }
515
-
516
- // Gather data for callbacks BEFORE clearing state
517
- const isCrossContainer = container !== originalContainer;
518
- let callbackData = null;
519
-
520
- if (enableCrossContainerPreview) {
521
- const draggedItem = stateRef.current.items.find(item => item && item.id === draggedItemId);
522
- const updatedItem = draggedItem ? { ...draggedItem, container } : null;
523
- const itemsInContainer = stateRef.current.items.filter(item => item && item.container === container);
524
- const indexInContainer = itemsInContainer.findIndex(item => item && item.id === draggedItemId);
525
- const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
526
- const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
527
-
528
- callbackData = { updatedItem, itemAbove, itemBelow };
529
- }
530
240
 
531
241
  dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
532
242
  dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
533
- dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
534
243
  changeCategory(state.dragData.id, container);
535
-
536
244
  if (onDrop) {
537
245
  if (!enableCrossContainerPreview) {
538
246
  onDrop(container);
539
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
+
540
256
  onDrop(
541
257
  draggedItemId,
542
258
  container,
543
259
  originalContainer,
544
- callbackData.updatedItem,
545
- callbackData.itemAbove,
546
- callbackData.itemBelow
260
+ updatedItem,
261
+ itemAbove,
262
+ itemBelow
547
263
  );
548
264
  }
549
265
  }
550
-
551
- // Trigger onDragEnd ONLY for cross-container drops (dragend doesn't fire reliably in that case)
552
- // For same-container drops, handleDragEnd will be called normally
553
- if (enableCrossContainerPreview && isCrossContainer && onDragEnd && callbackData) {
554
- onDragEnd(
555
- draggedItemId,
556
- container,
557
- originalContainer,
558
- callbackData.itemAbove,
559
- callbackData.itemBelow
560
- );
561
- }
562
266
  };
563
267
 
564
268
  const handleDragOver = (e: Event, container: string) => {
@@ -577,8 +281,6 @@ export const DraggableProvider = ({
577
281
  type: "MOVE_TO_CONTAINER_END",
578
282
  payload: { dragId: state.dragData.id, newContainer: container },
579
283
  });
580
- // Update current container in ref
581
- dragStateRef.current.currentContainer = container;
582
284
  }
583
285
  }
584
286
 
@@ -139,7 +139,8 @@ $text_colors: (
139
139
  text_lt_lighter: $text_lt_lighter,
140
140
  text_dk_default: $text_dk_default,
141
141
  text_dk_light: $text_dk_light,
142
- text_dk_lighter: $text_dk_lighter
142
+ text_dk_lighter: $text_dk_lighter,
143
+ text_dk_success_sm: $text_dk_success_sm
143
144
  );
144
145
 
145
146
  /* Data colors ------------------------*/