@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.
Files changed (59) hide show
  1. package/dist/types/components/DragAndDrop/Draggable/Draggable.d.ts +29 -0
  2. package/dist/types/components/DragAndDrop/Draggable/Draggable.example.d.ts +24 -0
  3. package/dist/types/components/DragAndDrop/Draggable/constants.d.ts +9 -0
  4. package/dist/types/components/DragAndDrop/Draggable/index.d.ts +1 -0
  5. package/dist/types/components/DragAndDrop/Draggable/types.d.ts +41 -0
  6. package/dist/types/components/DragAndDrop/Droppable/Droppable.d.ts +2 -0
  7. package/dist/types/components/DragAndDrop/Droppable/Droppable.example.d.ts +10 -0
  8. package/dist/types/components/DragAndDrop/Droppable/constants.d.ts +5 -0
  9. package/dist/types/components/DragAndDrop/Droppable/index.d.ts +1 -0
  10. package/dist/types/components/DragAndDrop/Droppable/types.d.ts +4 -0
  11. package/dist/types/components/DragAndDrop/Sortable/Sortable.d.ts +2 -0
  12. package/dist/types/components/DragAndDrop/Sortable/Sortable.example.d.ts +6 -0
  13. package/dist/types/components/DragAndDrop/Sortable/constants.d.ts +4 -0
  14. package/dist/types/components/DragAndDrop/Sortable/index.d.ts +1 -0
  15. package/dist/types/components/DragAndDrop/Sortable/types.d.ts +7 -0
  16. package/dist/types/components/DragAndDrop/index.d.ts +3 -0
  17. package/dist/types/components/Widget/InternalWidgetsContext.d.ts +2 -0
  18. package/dist/types/components/Widget/Widget.d.ts +2 -0
  19. package/dist/types/components/Widget/Widgets.example.d.ts +1 -0
  20. package/dist/types/components/Widget/WidgetsContext.d.ts +2 -0
  21. package/dist/types/components/Widget/hooks/index.d.ts +2 -0
  22. package/dist/types/components/Widget/hooks/useWidget/index.d.ts +1 -0
  23. package/dist/types/components/Widget/hooks/useWidget/useWidget.d.ts +7 -0
  24. package/dist/types/components/Widget/hooks/useWidgets/index.d.ts +1 -0
  25. package/dist/types/components/Widget/hooks/useWidgets/useWidgets.d.ts +1 -0
  26. package/dist/types/components/Widget/index.d.ts +3 -0
  27. package/dist/types/components/Widget/modifiers/index.d.ts +1 -0
  28. package/dist/types/components/Widget/modifiers/restrictToElement.d.ts +2 -0
  29. package/dist/types/components/Widget/types.d.ts +28 -0
  30. package/package.json +6 -2
  31. package/src/components/DragAndDrop/Draggable/Draggable.example.tsx +147 -0
  32. package/src/components/DragAndDrop/Draggable/Draggable.tsx +161 -0
  33. package/src/components/DragAndDrop/Draggable/constants.ts +47 -0
  34. package/src/components/DragAndDrop/Draggable/index.ts +1 -0
  35. package/src/components/DragAndDrop/Draggable/types.ts +56 -0
  36. package/src/components/DragAndDrop/Droppable/Droppable.example.tsx +86 -0
  37. package/src/components/DragAndDrop/Droppable/Droppable.tsx +38 -0
  38. package/src/components/DragAndDrop/Droppable/constants.ts +15 -0
  39. package/src/components/DragAndDrop/Droppable/index.ts +1 -0
  40. package/src/components/DragAndDrop/Droppable/types.ts +7 -0
  41. package/src/components/DragAndDrop/Sortable/Sortable.example.tsx +61 -0
  42. package/src/components/DragAndDrop/Sortable/Sortable.tsx +65 -0
  43. package/src/components/DragAndDrop/Sortable/constants.ts +12 -0
  44. package/src/components/DragAndDrop/Sortable/index.ts +1 -0
  45. package/src/components/DragAndDrop/Sortable/types.ts +11 -0
  46. package/src/components/DragAndDrop/index.ts +3 -0
  47. package/src/components/Widget/InternalWidgetsContext.tsx +4 -0
  48. package/src/components/Widget/Widget.tsx +17 -0
  49. package/src/components/Widget/Widgets.example.tsx +118 -0
  50. package/src/components/Widget/WidgetsContext.tsx +97 -0
  51. package/src/components/Widget/hooks/index.ts +2 -0
  52. package/src/components/Widget/hooks/useWidget/index.ts +1 -0
  53. package/src/components/Widget/hooks/useWidget/useWidget.ts +21 -0
  54. package/src/components/Widget/hooks/useWidgets/index.ts +1 -0
  55. package/src/components/Widget/hooks/useWidgets/useWidgets.ts +12 -0
  56. package/src/components/Widget/index.ts +3 -0
  57. package/src/components/Widget/modifiers/index.ts +1 -0
  58. package/src/components/Widget/modifiers/restrictToElement.ts +8 -0
  59. 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,2 @@
1
+ import { DroppableProps } from './types';
2
+ export declare const Droppable: ({ children, id, disabled, data, resizeObserverConfig, isDragging, className, ...props }: DroppableProps) => import("react/jsx-runtime").JSX.Element;
@@ -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,5 @@
1
+ export declare const getDroppableClasses: (props?: ({
2
+ isDragging?: boolean | null | undefined;
3
+ isOver?: boolean | null | undefined;
4
+ isEmpty?: boolean | null | undefined;
5
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
@@ -0,0 +1 @@
1
+ export { Droppable } from './Droppable';
@@ -0,0 +1,4 @@
1
+ import { UseDroppableArguments } from '@dnd-kit/core';
2
+ export type DroppableProps = Omit<React.HTMLAttributes<HTMLDivElement>, "id"> & UseDroppableArguments & Partial<{
3
+ isDragging: boolean;
4
+ }>;
@@ -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,4 @@
1
+ export declare const getSortableClasses: (props?: ({
2
+ isDragging?: boolean | null | undefined;
3
+ isSorting?: boolean | null | undefined;
4
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
@@ -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,3 @@
1
+ export { Draggable } from './Draggable';
2
+ export { Droppable } from './Droppable';
3
+ export { Sortable } from './Sortable';
@@ -0,0 +1,2 @@
1
+ import { InternalWidgetsContextProps } from './types';
2
+ export declare const InternalWidgetsContext: import('react').Context<InternalWidgetsContextProps | null>;
@@ -0,0 +1,2 @@
1
+ import { WidgetProps } from './types';
2
+ export declare const Widget: ({ id, children, actions, ...props }: WidgetProps) => import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1 @@
1
+ export declare const WidgetsExample: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { WidgetsContextProps } from './types';
2
+ export declare const WidgetsContext: ({ children, initialWidgets }: WidgetsContextProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { useWidget } from './useWidget';
2
+ export { useWidgets } from './useWidgets';
@@ -0,0 +1 @@
1
+ export { useWidget } from './useWidget';
@@ -0,0 +1,7 @@
1
+ import { UniqueIdentifier } from '@dnd-kit/core';
2
+ export declare const useWidget: (id: UniqueIdentifier) => {
3
+ widget: import('@dnd-kit/core').Data<{
4
+ id: UniqueIdentifier;
5
+ }> | undefined;
6
+ deleteWidget: () => void;
7
+ };
@@ -0,0 +1 @@
1
+ export { useWidgets } from './useWidgets';
@@ -0,0 +1 @@
1
+ export declare const useWidgets: () => import('../../types').InternalWidgetsContextProps;
@@ -0,0 +1,3 @@
1
+ export * from './hooks';
2
+ export { Widget } from './Widget';
3
+ export { WidgetsContext } from './WidgetsContext';
@@ -0,0 +1 @@
1
+ export { restrictToElement } from './restrictToElement';
@@ -0,0 +1,2 @@
1
+ import { Modifier } from '@dnd-kit/core';
2
+ export declare const restrictToElement: (rect: DOMRect | null | undefined) => Modifier;
@@ -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.45",
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": "097691180db90aaf22c9557d1f2f919246b167c1"
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";