feat: Add components required for estimates (#4690)
* Add sortable, radio and typography components * Remove stray css classes * Prevent drag of items from other draggable * Minor cleanup * Update yarn.lock * Remove radio input component as it was build on headless ui v2.0.0 and now we are using v1.7.0 * Fix build errors * Update dependencies in use memo.
This commit is contained in:
parent
77b73dc032
commit
188f8ff83f
9 changed files with 196 additions and 4 deletions
62
packages/ui/src/sortable/draggable.tsx
Normal file
62
packages/ui/src/sortable/draggable.tsx
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
|
||||
import { draggable, dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
|
||||
import { isEqual } from "lodash";
|
||||
import { cn } from "../../helpers";
|
||||
import { attachClosestEdge, extractClosestEdge } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
|
||||
import { DropIndicator } from "../drop-indicator";
|
||||
|
||||
type Props = {
|
||||
children: React.ReactNode;
|
||||
data: any; //@todo make this generic
|
||||
className?: string;
|
||||
};
|
||||
const Draggable = ({ children, data, className }: Props) => {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const [dragging, setDragging] = useState<boolean>(false); // NEW
|
||||
const [isDraggedOver, setIsDraggedOver] = useState(false);
|
||||
|
||||
const [closestEdge, setClosestEdge] = useState<string | null>(null);
|
||||
useEffect(() => {
|
||||
const el = ref.current;
|
||||
|
||||
if (el) {
|
||||
combine(
|
||||
draggable({
|
||||
element: el,
|
||||
onDragStart: () => setDragging(true), // NEW
|
||||
onDrop: () => setDragging(false), // NEW
|
||||
getInitialData: () => data,
|
||||
}),
|
||||
dropTargetForElements({
|
||||
element: el,
|
||||
onDragEnter: (args) => {
|
||||
setIsDraggedOver(true);
|
||||
setClosestEdge(extractClosestEdge(args.self.data));
|
||||
},
|
||||
onDragLeave: () => setIsDraggedOver(false),
|
||||
onDrop: () => {
|
||||
setIsDraggedOver(false);
|
||||
},
|
||||
canDrop: ({ source }) => !isEqual(source.data, data) && source.data.__uuid__ === data.__uuid__,
|
||||
getData: ({ input, element }) =>
|
||||
attachClosestEdge(data, {
|
||||
input,
|
||||
element,
|
||||
allowedEdges: ["top", "bottom"],
|
||||
}),
|
||||
})
|
||||
);
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<div ref={ref} className={cn(dragging && "opacity-25", className)}>
|
||||
{<DropIndicator isVisible={isDraggedOver && closestEdge === "top"} />}
|
||||
{children}
|
||||
{<DropIndicator isVisible={isDraggedOver && closestEdge === "bottom"} />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { Draggable };
|
||||
Loading…
Add table
Add a link
Reference in a new issue