sortableWidget.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import {useEffect} from 'react';
  2. import * as React from 'react';
  3. import {useSortable} from '@dnd-kit/sortable';
  4. import theme from 'app/utils/theme';
  5. import {Widget} from './types';
  6. import WidgetCard from './widgetCard';
  7. import WidgetWrapper from './widgetWrapper';
  8. const initialStyles: React.ComponentProps<typeof WidgetWrapper>['animate'] = {
  9. zIndex: 'auto',
  10. };
  11. type Props = {
  12. widget: Widget;
  13. dragId: string;
  14. isEditing: boolean;
  15. onDelete: () => void;
  16. onEdit: () => void;
  17. };
  18. function SortableWidget(props: Props) {
  19. const {widget, dragId, isEditing, onDelete, onEdit} = props;
  20. const {
  21. attributes,
  22. listeners,
  23. setNodeRef,
  24. transform,
  25. isDragging: currentWidgetDragging,
  26. isSorting,
  27. } = useSortable({
  28. id: dragId,
  29. transition: null,
  30. });
  31. useEffect(() => {
  32. if (!currentWidgetDragging) {
  33. return undefined;
  34. }
  35. document.body.style.cursor = 'grabbing';
  36. return function cleanup() {
  37. document.body.style.cursor = '';
  38. };
  39. }, [currentWidgetDragging]);
  40. return (
  41. <WidgetWrapper
  42. ref={setNodeRef}
  43. displayType={widget.displayType}
  44. layoutId={dragId}
  45. style={{
  46. // Origin is set to top right-hand corner where the drag handle is placed.
  47. // Otherwise, set the origin to be the top left-hand corner when swapping widgets.
  48. originX: currentWidgetDragging ? 1 : 0,
  49. originY: 0,
  50. boxShadow: currentWidgetDragging ? theme.dropShadowHeavy : 'none',
  51. borderRadius: currentWidgetDragging ? theme.borderRadius : undefined,
  52. }}
  53. animate={
  54. transform
  55. ? {
  56. x: transform.x,
  57. y: transform.y,
  58. scaleX: transform?.scaleX && transform.scaleX <= 1 ? transform.scaleX : 1,
  59. scaleY: transform?.scaleY && transform.scaleY <= 1 ? transform.scaleY : 1,
  60. zIndex: currentWidgetDragging ? theme.zIndex.modal : 'auto',
  61. }
  62. : initialStyles
  63. }
  64. transformTemplate={(___transform, generatedTransform) => {
  65. if (isEditing && !!transform) {
  66. return generatedTransform;
  67. }
  68. return 'none';
  69. }}
  70. transition={{
  71. duration: !currentWidgetDragging ? 0.25 : 0,
  72. easings: {
  73. type: 'spring',
  74. },
  75. }}
  76. >
  77. <WidgetCard
  78. widget={widget}
  79. isEditing={isEditing}
  80. onDelete={onDelete}
  81. onEdit={onEdit}
  82. isSorting={isSorting}
  83. hideToolbar={isSorting}
  84. currentWidgetDragging={currentWidgetDragging}
  85. draggableProps={{
  86. attributes,
  87. listeners,
  88. }}
  89. showContextMenu
  90. />
  91. </WidgetWrapper>
  92. );
  93. }
  94. export default SortableWidget;