@mbao01/common 0.0.45 → 0.0.46
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.
- package/dist/types/components/DragAndDrop/Draggable/Draggable.d.ts +29 -0
- package/dist/types/components/DragAndDrop/Draggable/Draggable.example.d.ts +24 -0
- package/dist/types/components/DragAndDrop/Draggable/constants.d.ts +9 -0
- package/dist/types/components/DragAndDrop/Draggable/index.d.ts +1 -0
- package/dist/types/components/DragAndDrop/Draggable/types.d.ts +41 -0
- package/dist/types/components/DragAndDrop/Droppable/Droppable.d.ts +2 -0
- package/dist/types/components/DragAndDrop/Droppable/Droppable.example.d.ts +10 -0
- package/dist/types/components/DragAndDrop/Droppable/constants.d.ts +5 -0
- package/dist/types/components/DragAndDrop/Droppable/index.d.ts +1 -0
- package/dist/types/components/DragAndDrop/Droppable/types.d.ts +4 -0
- package/dist/types/components/DragAndDrop/Sortable/Sortable.d.ts +2 -0
- package/dist/types/components/DragAndDrop/Sortable/Sortable.example.d.ts +6 -0
- package/dist/types/components/DragAndDrop/Sortable/constants.d.ts +4 -0
- package/dist/types/components/DragAndDrop/Sortable/index.d.ts +1 -0
- package/dist/types/components/DragAndDrop/Sortable/types.d.ts +7 -0
- package/dist/types/components/DragAndDrop/index.d.ts +3 -0
- package/dist/types/components/Widget/InternalWidgetsContext.d.ts +2 -0
- package/dist/types/components/Widget/Widget.d.ts +2 -0
- package/dist/types/components/Widget/Widgets.example.d.ts +1 -0
- package/dist/types/components/Widget/WidgetsContext.d.ts +2 -0
- package/dist/types/components/Widget/hooks/index.d.ts +2 -0
- package/dist/types/components/Widget/hooks/useWidget/index.d.ts +1 -0
- package/dist/types/components/Widget/hooks/useWidget/useWidget.d.ts +7 -0
- package/dist/types/components/Widget/hooks/useWidgets/index.d.ts +1 -0
- package/dist/types/components/Widget/hooks/useWidgets/useWidgets.d.ts +1 -0
- package/dist/types/components/Widget/index.d.ts +3 -0
- package/dist/types/components/Widget/modifiers/index.d.ts +1 -0
- package/dist/types/components/Widget/modifiers/restrictToElement.d.ts +2 -0
- package/dist/types/components/Widget/types.d.ts +28 -0
- package/package.json +6 -2
- package/src/components/DragAndDrop/Draggable/Draggable.example.tsx +147 -0
- package/src/components/DragAndDrop/Draggable/Draggable.tsx +161 -0
- package/src/components/DragAndDrop/Draggable/constants.ts +47 -0
- package/src/components/DragAndDrop/Draggable/index.ts +1 -0
- package/src/components/DragAndDrop/Draggable/types.ts +56 -0
- package/src/components/DragAndDrop/Droppable/Droppable.example.tsx +86 -0
- package/src/components/DragAndDrop/Droppable/Droppable.tsx +38 -0
- package/src/components/DragAndDrop/Droppable/constants.ts +15 -0
- package/src/components/DragAndDrop/Droppable/index.ts +1 -0
- package/src/components/DragAndDrop/Droppable/types.ts +7 -0
- package/src/components/DragAndDrop/Sortable/Sortable.example.tsx +61 -0
- package/src/components/DragAndDrop/Sortable/Sortable.tsx +65 -0
- package/src/components/DragAndDrop/Sortable/constants.ts +12 -0
- package/src/components/DragAndDrop/Sortable/index.ts +1 -0
- package/src/components/DragAndDrop/Sortable/types.ts +11 -0
- package/src/components/DragAndDrop/index.ts +3 -0
- package/src/components/Widget/InternalWidgetsContext.tsx +4 -0
- package/src/components/Widget/Widget.tsx +17 -0
- package/src/components/Widget/Widgets.example.tsx +118 -0
- package/src/components/Widget/WidgetsContext.tsx +97 -0
- package/src/components/Widget/hooks/index.ts +2 -0
- package/src/components/Widget/hooks/useWidget/index.ts +1 -0
- package/src/components/Widget/hooks/useWidget/useWidget.ts +21 -0
- package/src/components/Widget/hooks/useWidgets/index.ts +1 -0
- package/src/components/Widget/hooks/useWidgets/useWidgets.ts +12 -0
- package/src/components/Widget/index.ts +3 -0
- package/src/components/Widget/modifiers/index.ts +1 -0
- package/src/components/Widget/modifiers/restrictToElement.ts +8 -0
- package/src/components/Widget/types.ts +30 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { CSSProperties, Ref } from 'react';
|
|
2
|
+
import { DraggableOverlayProps, DraggableProps } from './types';
|
|
3
|
+
declare const Draggable: {
|
|
4
|
+
({ id, axis, data, disabled, attributes, style, handle, className, ...props }: DraggableProps): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
Root: import('react').ForwardRefExoticComponent<Partial<{
|
|
6
|
+
axis: import('./types').DraggableAxis;
|
|
7
|
+
style: CSSProperties;
|
|
8
|
+
handle: import('./types').DraggableHandleElement;
|
|
9
|
+
actions: (args: Partial<import('./types').DraggableActionsArgs>) => import('react').ReactNode;
|
|
10
|
+
}> & import('react').HTMLAttributes<HTMLDivElement> & Partial<{
|
|
11
|
+
isDragOverlay: boolean;
|
|
12
|
+
isDragging: boolean;
|
|
13
|
+
listeners: import('@dnd-kit/core').DraggableSyntheticListeners;
|
|
14
|
+
transform: import('@dnd-kit/utilities').Transform | null;
|
|
15
|
+
activatorNodeRef: Ref<HTMLElement>;
|
|
16
|
+
}> & import('react').RefAttributes<HTMLDivElement>>;
|
|
17
|
+
Action: import('react').ForwardRefExoticComponent<import('react').HTMLAttributes<HTMLButtonElement> & {
|
|
18
|
+
active?: Partial<{
|
|
19
|
+
fill: string;
|
|
20
|
+
background: string;
|
|
21
|
+
}>;
|
|
22
|
+
cursor?: CSSProperties["cursor"];
|
|
23
|
+
} & import('react').RefAttributes<HTMLElement>>;
|
|
24
|
+
Overlay: {
|
|
25
|
+
({ axis, dropAnimation, className, ...props }: DraggableOverlayProps): import('react').ReactPortal;
|
|
26
|
+
displayName: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
export { Draggable };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { DropAnimation, Modifiers, PointerActivationConstraint } from '@dnd-kit/core';
|
|
2
|
+
import { CSSProperties } from 'react';
|
|
3
|
+
import { DraggableAxis, DraggableHandleElement } from './types';
|
|
4
|
+
type DraggableExampleProps = Partial<{
|
|
5
|
+
activationConstraint: PointerActivationConstraint;
|
|
6
|
+
axis: DraggableAxis;
|
|
7
|
+
handle: DraggableHandleElement;
|
|
8
|
+
modifiers: Modifiers;
|
|
9
|
+
buttonStyle: CSSProperties;
|
|
10
|
+
label: string;
|
|
11
|
+
}>;
|
|
12
|
+
export declare const DraggableExample: ({ activationConstraint, axis, handle, modifiers, label, }: DraggableExampleProps) => import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export declare const DraggableSnapToGridExample: () => import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
type DraggableOverlayExampleProps = Partial<{
|
|
15
|
+
activationConstraint: PointerActivationConstraint;
|
|
16
|
+
axis: DraggableAxis;
|
|
17
|
+
handle: DraggableHandleElement;
|
|
18
|
+
modifiers: Modifiers;
|
|
19
|
+
label: string;
|
|
20
|
+
dragOverlayModifiers: Modifiers;
|
|
21
|
+
dropAnimation: DropAnimation | null;
|
|
22
|
+
}>;
|
|
23
|
+
export declare const DraggableOverlayExample: ({ axis, dropAnimation, handle, label, modifiers, }: DraggableOverlayExampleProps) => import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { DropAnimation } from '@dnd-kit/core';
|
|
2
|
+
export declare const DROP_ANIMATION_CONFIG: DropAnimation;
|
|
3
|
+
export declare const getDraggableClasses: (props?: ({
|
|
4
|
+
isDragging?: boolean | null | undefined;
|
|
5
|
+
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
6
|
+
export declare const getDraggableRootClasses: (props?: ({
|
|
7
|
+
isDragging?: boolean | null | undefined;
|
|
8
|
+
isDragOverlay?: boolean | null | undefined;
|
|
9
|
+
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Draggable } from './Draggable';
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { DraggableSyntheticListeners, DragOverlayProps, DropAnimation, UseDraggableArguments } from '@dnd-kit/core';
|
|
2
|
+
import { CSSProperties, ReactNode, Ref } from 'react';
|
|
3
|
+
import { Transform } from '@dnd-kit/utilities';
|
|
4
|
+
export declare enum DraggableAxis {
|
|
5
|
+
All = 0,
|
|
6
|
+
Vertical = 1,
|
|
7
|
+
Horizontal = 2
|
|
8
|
+
}
|
|
9
|
+
export type DraggableHandleElement = JSX.Element | null;
|
|
10
|
+
export type DraggableActionsArgs = {
|
|
11
|
+
draggable: {
|
|
12
|
+
ref: Ref<HTMLElement> | undefined;
|
|
13
|
+
listeners: DraggableSyntheticListeners;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
type BaseDraggableProps = Partial<{
|
|
17
|
+
axis: DraggableAxis;
|
|
18
|
+
style: CSSProperties;
|
|
19
|
+
handle: DraggableHandleElement;
|
|
20
|
+
actions: (args: Partial<DraggableActionsArgs>) => ReactNode;
|
|
21
|
+
}> & React.HTMLAttributes<HTMLDivElement>;
|
|
22
|
+
export type DraggableProps = BaseDraggableProps & UseDraggableArguments;
|
|
23
|
+
export type DraggableRootProps = BaseDraggableProps & Partial<{
|
|
24
|
+
isDragOverlay: boolean;
|
|
25
|
+
isDragging: boolean;
|
|
26
|
+
listeners: DraggableSyntheticListeners;
|
|
27
|
+
transform: Transform | null;
|
|
28
|
+
activatorNodeRef: Ref<HTMLElement>;
|
|
29
|
+
}>;
|
|
30
|
+
export type DraggableActionProps = React.HTMLAttributes<HTMLButtonElement> & {
|
|
31
|
+
active?: Partial<{
|
|
32
|
+
fill: string;
|
|
33
|
+
background: string;
|
|
34
|
+
}>;
|
|
35
|
+
cursor?: CSSProperties["cursor"];
|
|
36
|
+
};
|
|
37
|
+
export type DraggableOverlayProps = {
|
|
38
|
+
axis?: DraggableRootProps["axis"];
|
|
39
|
+
dropAnimation?: DropAnimation | null;
|
|
40
|
+
} & DragOverlayProps;
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Modifiers, UniqueIdentifier } from '@dnd-kit/core';
|
|
2
|
+
type CollisionDetectionType = "rectIntersection" | "closestCenter" | "closestCorners" | "pointerWithin";
|
|
3
|
+
type DroppableExampleProps = {
|
|
4
|
+
collisionDetection?: CollisionDetectionType;
|
|
5
|
+
containers?: UniqueIdentifier[];
|
|
6
|
+
modifiers?: Modifiers;
|
|
7
|
+
};
|
|
8
|
+
export declare const DroppableExample: ({ containers, collisionDetection, modifiers, }: DroppableExampleProps) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export declare const CollisionDetectionAlgorithmsDroppableExample: ({ collisionDetection, ...props }: DroppableExampleProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Droppable } from './Droppable';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { SortableProps } from './types';
|
|
2
|
+
export declare const Sortable: ({ id, data, style, className, children, disabled, attributes, resizeObserverConfig, animateLayoutChanges, getNewIndex, strategy, transition, ...props }: SortableProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { SortableProps } from './types';
|
|
2
|
+
type SortableExampleProps = Partial<SortableProps> & {
|
|
3
|
+
hasDraggableOverlay?: boolean;
|
|
4
|
+
};
|
|
5
|
+
export declare const SortableExample: ({ hasDraggableOverlay, ...props }: SortableExampleProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Sortable } from './Sortable';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { UseSortableArguments } from '@dnd-kit/sortable';
|
|
2
|
+
import { CSSProperties } from 'react';
|
|
3
|
+
import { DraggableAxis, DraggableRootProps } from '../Draggable/types';
|
|
4
|
+
export type SortableProps = Omit<React.HTMLAttributes<HTMLDivElement>, "id"> & UseSortableArguments & Pick<DraggableRootProps, "handle" | "actions"> & Partial<{
|
|
5
|
+
axis: DraggableAxis;
|
|
6
|
+
style: CSSProperties;
|
|
7
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const WidgetsExample: () => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useWidget } from './useWidget';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useWidgets } from './useWidgets';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useWidgets: () => import('../../types').InternalWidgetsContextProps;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { restrictToElement } from './restrictToElement';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Data, UniqueIdentifier } from '@dnd-kit/core';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { DraggableActionsArgs } from '../DragAndDrop/Draggable/types';
|
|
4
|
+
import { SortableProps } from '../DragAndDrop/Sortable/types';
|
|
5
|
+
export type Widget = Data<{
|
|
6
|
+
id: UniqueIdentifier;
|
|
7
|
+
}>;
|
|
8
|
+
type WidgetActions = (args: Partial<DraggableActionsArgs> & {
|
|
9
|
+
deleteWidget: () => void;
|
|
10
|
+
}) => ReactNode;
|
|
11
|
+
export type WidgetProps = Omit<SortableProps, "actions"> & {
|
|
12
|
+
actions?: WidgetActions;
|
|
13
|
+
};
|
|
14
|
+
export type WidgetsContextProps = {
|
|
15
|
+
children?: ReactNode;
|
|
16
|
+
initialWidgets?: Widget[];
|
|
17
|
+
};
|
|
18
|
+
export type InternalWidgetsContextProps = {
|
|
19
|
+
widgets: Data<{
|
|
20
|
+
id: UniqueIdentifier;
|
|
21
|
+
}>[];
|
|
22
|
+
addWidget: (widget: Widget, insertIndex?: number) => void;
|
|
23
|
+
addWidgets: (widgets: Widget[], startIndex?: number) => void;
|
|
24
|
+
deleteWidget: (widget: Widget) => void;
|
|
25
|
+
deleteWidgets: (widgets: Widget[]) => void;
|
|
26
|
+
resetWidgets: () => void;
|
|
27
|
+
};
|
|
28
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mbao01/common",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.46",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Ayomide Bakare",
|
|
7
7
|
"license": "MIT",
|
|
@@ -68,6 +68,10 @@
|
|
|
68
68
|
"test:watch": "vitest"
|
|
69
69
|
},
|
|
70
70
|
"dependencies": {
|
|
71
|
+
"@dnd-kit/core": "^6.1.0",
|
|
72
|
+
"@dnd-kit/modifiers": "^7.0.0",
|
|
73
|
+
"@dnd-kit/sortable": "^8.0.0",
|
|
74
|
+
"@dnd-kit/utilities": "^3.2.2",
|
|
71
75
|
"@radix-ui/react-accordion": "^1.2.0",
|
|
72
76
|
"@radix-ui/react-alert-dialog": "^1.1.1",
|
|
73
77
|
"@radix-ui/react-avatar": "^1.1.0",
|
|
@@ -167,5 +171,5 @@
|
|
|
167
171
|
"react-dom": "^18.2.0",
|
|
168
172
|
"typescript": "^5.2.2"
|
|
169
173
|
},
|
|
170
|
-
"gitHead": "
|
|
174
|
+
"gitHead": "541e3f7084b5e39d30b3ce90140ede22d75e1889"
|
|
171
175
|
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import type { DropAnimation, Modifiers, PointerActivationConstraint } from "@dnd-kit/core";
|
|
2
|
+
import type { Coordinates } from "@dnd-kit/utilities";
|
|
3
|
+
import type { CSSProperties } from "react";
|
|
4
|
+
import { useMemo, useState } from "react";
|
|
5
|
+
import {
|
|
6
|
+
DndContext,
|
|
7
|
+
KeyboardSensor,
|
|
8
|
+
MouseSensor,
|
|
9
|
+
TouchSensor,
|
|
10
|
+
useSensor,
|
|
11
|
+
useSensors,
|
|
12
|
+
} from "@dnd-kit/core";
|
|
13
|
+
import { createSnapModifier } from "@dnd-kit/modifiers";
|
|
14
|
+
import type { DraggableAxis } from "./types";
|
|
15
|
+
import { Draggable } from "./Draggable";
|
|
16
|
+
import { type DraggableHandleElement } from "./types";
|
|
17
|
+
|
|
18
|
+
type DraggableExampleProps = Partial<{
|
|
19
|
+
activationConstraint: PointerActivationConstraint;
|
|
20
|
+
axis: DraggableAxis;
|
|
21
|
+
handle: DraggableHandleElement;
|
|
22
|
+
modifiers: Modifiers;
|
|
23
|
+
buttonStyle: CSSProperties;
|
|
24
|
+
label: string;
|
|
25
|
+
}>;
|
|
26
|
+
|
|
27
|
+
export const DraggableExample = ({
|
|
28
|
+
activationConstraint,
|
|
29
|
+
axis,
|
|
30
|
+
handle,
|
|
31
|
+
modifiers,
|
|
32
|
+
label = "Go ahead, drag me.",
|
|
33
|
+
}: DraggableExampleProps) => {
|
|
34
|
+
const [{ x, y }, setCoordinates] = useState<Coordinates>({ x: 0, y: 0 });
|
|
35
|
+
const mouseSensor = useSensor(MouseSensor, {
|
|
36
|
+
activationConstraint,
|
|
37
|
+
});
|
|
38
|
+
const touchSensor = useSensor(TouchSensor, {
|
|
39
|
+
activationConstraint,
|
|
40
|
+
});
|
|
41
|
+
const keyboardSensor = useSensor(KeyboardSensor, {});
|
|
42
|
+
const sensors = useSensors(mouseSensor, touchSensor, keyboardSensor);
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<DndContext
|
|
46
|
+
sensors={sensors}
|
|
47
|
+
onDragEnd={({ delta }) => {
|
|
48
|
+
setCoordinates(({ x, y }) => {
|
|
49
|
+
return {
|
|
50
|
+
x: x + delta.x,
|
|
51
|
+
y: y + delta.y,
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
}}
|
|
55
|
+
modifiers={modifiers}
|
|
56
|
+
>
|
|
57
|
+
<Draggable
|
|
58
|
+
id="my-draggable"
|
|
59
|
+
axis={axis}
|
|
60
|
+
handle={handle}
|
|
61
|
+
style={{ top: y, left: x }}
|
|
62
|
+
className="w-fit border border-base-content rounded-md p-2 flex items-center gap-2"
|
|
63
|
+
>
|
|
64
|
+
{label}
|
|
65
|
+
</Draggable>
|
|
66
|
+
</DndContext>
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const DraggableSnapToGridExample = () => {
|
|
71
|
+
const [gridSize] = useState(30);
|
|
72
|
+
const buttonStyle = {
|
|
73
|
+
marginLeft: gridSize - 20 + 1,
|
|
74
|
+
marginTop: gridSize - 20 + 1,
|
|
75
|
+
width: gridSize * 8 - 1,
|
|
76
|
+
height: gridSize * 2 - 1,
|
|
77
|
+
};
|
|
78
|
+
const snapToGrid = useMemo(() => createSnapModifier(gridSize), [gridSize]);
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<>
|
|
82
|
+
<DraggableExample
|
|
83
|
+
label={`Snapping to ${gridSize}px increments`}
|
|
84
|
+
modifiers={[snapToGrid]}
|
|
85
|
+
buttonStyle={buttonStyle}
|
|
86
|
+
key={gridSize}
|
|
87
|
+
/>
|
|
88
|
+
<div
|
|
89
|
+
className="fixed top-0 left-0 w-full h-full -z-10 pointer-events-none"
|
|
90
|
+
style={
|
|
91
|
+
{
|
|
92
|
+
"--grid-size": `${gridSize}px`,
|
|
93
|
+
backgroundSize: "var(--grid-size) var(--grid-size)",
|
|
94
|
+
backgroundImage: `repeating-linear-gradient(
|
|
95
|
+
0deg,
|
|
96
|
+
transparent,
|
|
97
|
+
transparent calc(var(--grid-size) - 1px),
|
|
98
|
+
#9999991a calc(var(--grid-size) - 1px),
|
|
99
|
+
#9999991a var(--grid-size)
|
|
100
|
+
),
|
|
101
|
+
repeating-linear-gradient(
|
|
102
|
+
-90deg,
|
|
103
|
+
transparent,
|
|
104
|
+
transparent calc(var(--grid-size) - 1px),
|
|
105
|
+
#9999991a calc(var(--grid-size) - 1px),
|
|
106
|
+
#9999991a var(--grid-size)
|
|
107
|
+
)`,
|
|
108
|
+
} as React.CSSProperties
|
|
109
|
+
}
|
|
110
|
+
/>
|
|
111
|
+
</>
|
|
112
|
+
);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
type DraggableOverlayExampleProps = Partial<{
|
|
116
|
+
activationConstraint: PointerActivationConstraint;
|
|
117
|
+
axis: DraggableAxis;
|
|
118
|
+
handle: DraggableHandleElement;
|
|
119
|
+
modifiers: Modifiers;
|
|
120
|
+
label: string;
|
|
121
|
+
dragOverlayModifiers: Modifiers;
|
|
122
|
+
dropAnimation: DropAnimation | null;
|
|
123
|
+
}>;
|
|
124
|
+
|
|
125
|
+
export const DraggableOverlayExample = ({
|
|
126
|
+
axis,
|
|
127
|
+
dropAnimation,
|
|
128
|
+
handle,
|
|
129
|
+
label = "Drag me to see the <Draggable.Overlay>",
|
|
130
|
+
modifiers,
|
|
131
|
+
}: DraggableOverlayExampleProps) => {
|
|
132
|
+
return (
|
|
133
|
+
<DndContext modifiers={modifiers}>
|
|
134
|
+
<div>
|
|
135
|
+
<Draggable
|
|
136
|
+
id="my-draggable"
|
|
137
|
+
axis={axis}
|
|
138
|
+
handle={handle}
|
|
139
|
+
className="w-fit border border-base-content rounded-md p-2 flex items-center gap-2 data-[draggable-active]:opacity-0"
|
|
140
|
+
>
|
|
141
|
+
{label}
|
|
142
|
+
</Draggable>
|
|
143
|
+
</div>
|
|
144
|
+
<Draggable.Overlay axis={axis} dropAnimation={dropAnimation} />
|
|
145
|
+
</DndContext>
|
|
146
|
+
);
|
|
147
|
+
};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type { CSSProperties, Ref } from "react";
|
|
4
|
+
import { forwardRef } from "react";
|
|
5
|
+
import { createPortal } from "react-dom";
|
|
6
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
7
|
+
import { DragOverlay, useDndContext, useDraggable } from "@dnd-kit/core";
|
|
8
|
+
import type {
|
|
9
|
+
DraggableActionProps,
|
|
10
|
+
DraggableOverlayProps,
|
|
11
|
+
DraggableProps,
|
|
12
|
+
DraggableRootProps,
|
|
13
|
+
} from "./types";
|
|
14
|
+
import { cn } from "../../../utilities";
|
|
15
|
+
import { DROP_ANIMATION_CONFIG, getDraggableClasses, getDraggableRootClasses } from "./constants";
|
|
16
|
+
|
|
17
|
+
const Draggable = ({
|
|
18
|
+
id,
|
|
19
|
+
axis,
|
|
20
|
+
data,
|
|
21
|
+
disabled,
|
|
22
|
+
attributes,
|
|
23
|
+
style,
|
|
24
|
+
handle,
|
|
25
|
+
className,
|
|
26
|
+
...props
|
|
27
|
+
}: DraggableProps) => {
|
|
28
|
+
const {
|
|
29
|
+
attributes: draggableAttributes,
|
|
30
|
+
isDragging,
|
|
31
|
+
listeners,
|
|
32
|
+
transform,
|
|
33
|
+
setNodeRef,
|
|
34
|
+
setActivatorNodeRef,
|
|
35
|
+
} = useDraggable({
|
|
36
|
+
id,
|
|
37
|
+
data,
|
|
38
|
+
disabled,
|
|
39
|
+
attributes,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<DraggableRoot
|
|
44
|
+
{...props}
|
|
45
|
+
{...draggableAttributes}
|
|
46
|
+
ref={setNodeRef}
|
|
47
|
+
activatorNodeRef={setActivatorNodeRef}
|
|
48
|
+
axis={axis}
|
|
49
|
+
handle={handle}
|
|
50
|
+
isDragging={isDragging}
|
|
51
|
+
listeners={listeners}
|
|
52
|
+
transform={transform}
|
|
53
|
+
style={style}
|
|
54
|
+
className={cn(className, getDraggableClasses({ isDragging }))}
|
|
55
|
+
data-draggable={true}
|
|
56
|
+
data-draggable-active={isDragging || undefined}
|
|
57
|
+
/>
|
|
58
|
+
);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const DraggableRoot = forwardRef<HTMLDivElement, DraggableRootProps>(
|
|
62
|
+
(
|
|
63
|
+
{
|
|
64
|
+
handle,
|
|
65
|
+
actions,
|
|
66
|
+
activatorNodeRef,
|
|
67
|
+
className,
|
|
68
|
+
isDragging,
|
|
69
|
+
isDragOverlay,
|
|
70
|
+
listeners,
|
|
71
|
+
transform,
|
|
72
|
+
style,
|
|
73
|
+
children,
|
|
74
|
+
...props
|
|
75
|
+
},
|
|
76
|
+
ref
|
|
77
|
+
) => {
|
|
78
|
+
const draggable = { listeners, ref: activatorNodeRef };
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<div
|
|
82
|
+
{...props}
|
|
83
|
+
{...(actions || handle ? {} : listeners)}
|
|
84
|
+
ref={ref}
|
|
85
|
+
style={
|
|
86
|
+
{
|
|
87
|
+
...style,
|
|
88
|
+
"--translate-x": `${transform?.x ?? 0}px`,
|
|
89
|
+
"--translate-y": `${transform?.y ?? 0}px`,
|
|
90
|
+
} as CSSProperties
|
|
91
|
+
}
|
|
92
|
+
className={cn(className, getDraggableRootClasses({ isDragging, isDragOverlay }))}
|
|
93
|
+
>
|
|
94
|
+
{actions?.({ draggable })}
|
|
95
|
+
{handle ? (
|
|
96
|
+
<Slot {...draggable.listeners} ref={draggable.ref}>
|
|
97
|
+
{handle}
|
|
98
|
+
</Slot>
|
|
99
|
+
) : null}
|
|
100
|
+
{children}
|
|
101
|
+
</div>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
);
|
|
105
|
+
DraggableRoot.displayName = "DraggableRoot";
|
|
106
|
+
|
|
107
|
+
const DraggableAction = forwardRef<HTMLElement, DraggableActionProps>(
|
|
108
|
+
({ active, children, className, cursor, style, ...props }, ref) => {
|
|
109
|
+
return (
|
|
110
|
+
<button
|
|
111
|
+
ref={ref as Ref<HTMLButtonElement>}
|
|
112
|
+
{...props}
|
|
113
|
+
tabIndex={0}
|
|
114
|
+
className={className}
|
|
115
|
+
style={
|
|
116
|
+
{
|
|
117
|
+
...style,
|
|
118
|
+
cursor,
|
|
119
|
+
"--fill": active?.fill,
|
|
120
|
+
"--background": active?.background,
|
|
121
|
+
} as CSSProperties
|
|
122
|
+
}
|
|
123
|
+
>
|
|
124
|
+
{children}
|
|
125
|
+
</button>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
);
|
|
129
|
+
DraggableAction.displayName = "DraggableAction";
|
|
130
|
+
|
|
131
|
+
const DraggableOverlay = ({
|
|
132
|
+
axis,
|
|
133
|
+
dropAnimation = DROP_ANIMATION_CONFIG,
|
|
134
|
+
className,
|
|
135
|
+
...props
|
|
136
|
+
}: DraggableOverlayProps) => {
|
|
137
|
+
const { active, activeNode } = useDndContext();
|
|
138
|
+
|
|
139
|
+
return createPortal(
|
|
140
|
+
<DragOverlay dropAnimation={dropAnimation} {...props}>
|
|
141
|
+
{active ? (
|
|
142
|
+
<DraggableRoot
|
|
143
|
+
axis={axis}
|
|
144
|
+
isDragging
|
|
145
|
+
isDragOverlay
|
|
146
|
+
className={cn(className, activeNode?.className)}
|
|
147
|
+
>
|
|
148
|
+
<div dangerouslySetInnerHTML={{ __html: activeNode?.innerHTML ?? "" }} />
|
|
149
|
+
</DraggableRoot>
|
|
150
|
+
) : null}
|
|
151
|
+
</DragOverlay>,
|
|
152
|
+
document.body
|
|
153
|
+
);
|
|
154
|
+
};
|
|
155
|
+
DraggableOverlay.displayName = "DraggableOverlay";
|
|
156
|
+
|
|
157
|
+
Draggable.Root = DraggableRoot;
|
|
158
|
+
Draggable.Action = DraggableAction;
|
|
159
|
+
Draggable.Overlay = DraggableOverlay;
|
|
160
|
+
|
|
161
|
+
export { Draggable };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { DropAnimation } from "@dnd-kit/core";
|
|
2
|
+
import { CSS } from "@dnd-kit/utilities";
|
|
3
|
+
import { cva } from "../../../libs";
|
|
4
|
+
|
|
5
|
+
export const DROP_ANIMATION_CONFIG: DropAnimation = {
|
|
6
|
+
keyframes({ transform }) {
|
|
7
|
+
return [
|
|
8
|
+
{ transform: CSS.Transform.toString(transform.initial) },
|
|
9
|
+
{
|
|
10
|
+
transform: CSS.Transform.toString({
|
|
11
|
+
...transform.final,
|
|
12
|
+
scaleX: 0.96,
|
|
13
|
+
scaleY: 0.96,
|
|
14
|
+
}),
|
|
15
|
+
},
|
|
16
|
+
];
|
|
17
|
+
},
|
|
18
|
+
sideEffects({ active }) {
|
|
19
|
+
active.node.style.opacity = "0";
|
|
20
|
+
|
|
21
|
+
return () => {
|
|
22
|
+
active.node.style.opacity = "";
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const getDraggableClasses = cva(
|
|
28
|
+
"translate-x-[--translate-x] translate-y-[--translate-y] translate-z-0",
|
|
29
|
+
{
|
|
30
|
+
variants: {
|
|
31
|
+
isDragging: {
|
|
32
|
+
true: "transition-none z-10 cursor-grabbing",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
export const getDraggableRootClasses = cva("relative", {
|
|
39
|
+
variants: {
|
|
40
|
+
isDragging: {
|
|
41
|
+
true: "",
|
|
42
|
+
},
|
|
43
|
+
isDragOverlay: {
|
|
44
|
+
true: "",
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Draggable } from "./Draggable";
|