@mbao01/common 0.0.45 → 0.0.47

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 (70) hide show
  1. package/dist/types/components/Chart/helpers.d.ts +3 -1
  2. package/dist/types/components/Chart/stories/args/index.d.ts +63 -0
  3. package/dist/types/components/DragAndDrop/Draggable/Draggable.d.ts +29 -0
  4. package/dist/types/components/DragAndDrop/Draggable/Draggable.example.d.ts +24 -0
  5. package/dist/types/components/DragAndDrop/Draggable/constants.d.ts +9 -0
  6. package/dist/types/components/DragAndDrop/Draggable/index.d.ts +1 -0
  7. package/dist/types/components/DragAndDrop/Draggable/types.d.ts +41 -0
  8. package/dist/types/components/DragAndDrop/Droppable/Droppable.d.ts +2 -0
  9. package/dist/types/components/DragAndDrop/Droppable/Droppable.example.d.ts +10 -0
  10. package/dist/types/components/DragAndDrop/Droppable/constants.d.ts +5 -0
  11. package/dist/types/components/DragAndDrop/Droppable/index.d.ts +1 -0
  12. package/dist/types/components/DragAndDrop/Droppable/types.d.ts +4 -0
  13. package/dist/types/components/DragAndDrop/Sortable/Sortable.d.ts +2 -0
  14. package/dist/types/components/DragAndDrop/Sortable/Sortable.example.d.ts +6 -0
  15. package/dist/types/components/DragAndDrop/Sortable/constants.d.ts +4 -0
  16. package/dist/types/components/DragAndDrop/Sortable/index.d.ts +1 -0
  17. package/dist/types/components/DragAndDrop/Sortable/types.d.ts +7 -0
  18. package/dist/types/components/DragAndDrop/index.d.ts +3 -0
  19. package/dist/types/components/Form/DatetimeInput/DatetimeInput.d.ts +1 -1
  20. package/dist/types/components/Menu/Menubar/Menubar.d.ts +42 -0
  21. package/dist/types/components/Menu/Menubar/types.d.ts +1 -0
  22. package/dist/types/components/Widget/InternalWidgetsContext.d.ts +2 -0
  23. package/dist/types/components/Widget/Widget.d.ts +2 -0
  24. package/dist/types/components/Widget/Widgets.example.d.ts +1 -0
  25. package/dist/types/components/Widget/WidgetsContext.d.ts +2 -0
  26. package/dist/types/components/Widget/hooks/index.d.ts +2 -0
  27. package/dist/types/components/Widget/hooks/useWidget/index.d.ts +1 -0
  28. package/dist/types/components/Widget/hooks/useWidget/useWidget.d.ts +7 -0
  29. package/dist/types/components/Widget/hooks/useWidgets/index.d.ts +1 -0
  30. package/dist/types/components/Widget/hooks/useWidgets/useWidgets.d.ts +1 -0
  31. package/dist/types/components/Widget/index.d.ts +3 -0
  32. package/dist/types/components/Widget/modifiers/index.d.ts +1 -0
  33. package/dist/types/components/Widget/modifiers/restrictToElement.d.ts +2 -0
  34. package/dist/types/components/Widget/types.d.ts +28 -0
  35. package/dist/types/index.d.ts +2 -0
  36. package/package.json +63 -59
  37. package/src/components/Chart/helpers.ts +14 -8
  38. package/src/components/Chart/stories/args/index.ts +12 -12
  39. package/src/components/DragAndDrop/Draggable/Draggable.example.tsx +147 -0
  40. package/src/components/DragAndDrop/Draggable/Draggable.tsx +161 -0
  41. package/src/components/DragAndDrop/Draggable/constants.ts +47 -0
  42. package/src/components/DragAndDrop/Draggable/index.ts +1 -0
  43. package/src/components/DragAndDrop/Draggable/types.ts +56 -0
  44. package/src/components/DragAndDrop/Droppable/Droppable.example.tsx +86 -0
  45. package/src/components/DragAndDrop/Droppable/Droppable.tsx +38 -0
  46. package/src/components/DragAndDrop/Droppable/constants.ts +15 -0
  47. package/src/components/DragAndDrop/Droppable/index.ts +1 -0
  48. package/src/components/DragAndDrop/Droppable/types.ts +7 -0
  49. package/src/components/DragAndDrop/Sortable/Sortable.example.tsx +61 -0
  50. package/src/components/DragAndDrop/Sortable/Sortable.tsx +65 -0
  51. package/src/components/DragAndDrop/Sortable/constants.ts +12 -0
  52. package/src/components/DragAndDrop/Sortable/index.ts +1 -0
  53. package/src/components/DragAndDrop/Sortable/types.ts +11 -0
  54. package/src/components/DragAndDrop/index.ts +3 -0
  55. package/src/components/Menu/Menubar/Menubar.tsx +5 -1
  56. package/src/components/Menu/Menubar/types.ts +2 -0
  57. package/src/components/Widget/InternalWidgetsContext.tsx +4 -0
  58. package/src/components/Widget/Widget.tsx +17 -0
  59. package/src/components/Widget/Widgets.example.tsx +118 -0
  60. package/src/components/Widget/WidgetsContext.tsx +97 -0
  61. package/src/components/Widget/hooks/index.ts +2 -0
  62. package/src/components/Widget/hooks/useWidget/index.ts +1 -0
  63. package/src/components/Widget/hooks/useWidget/useWidget.ts +21 -0
  64. package/src/components/Widget/hooks/useWidgets/index.ts +1 -0
  65. package/src/components/Widget/hooks/useWidgets/useWidgets.ts +12 -0
  66. package/src/components/Widget/index.ts +3 -0
  67. package/src/components/Widget/modifiers/index.ts +1 -0
  68. package/src/components/Widget/modifiers/restrictToElement.ts +8 -0
  69. package/src/components/Widget/types.ts +30 -0
  70. package/src/index.ts +2 -0
@@ -1,26 +1,32 @@
1
+ import type {
2
+ NameType,
3
+ Payload as TooltipPayload,
4
+ ValueType,
5
+ } from "recharts/types/component/DefaultTooltipContent";
6
+ import { type Payload as LegendPayload } from "recharts/types/component/DefaultLegendContent";
1
7
  import { type ChartConfig } from "./types";
2
8
 
3
9
  // Helper to extract item config from a payload.
4
- export const getPayloadConfigFromPayload = (config: ChartConfig, payload: unknown, key: string) => {
10
+ export const getPayloadConfigFromPayload = (
11
+ config: ChartConfig,
12
+ payload: LegendPayload | TooltipPayload<ValueType, NameType>,
13
+ key: string
14
+ ) => {
5
15
  if (typeof payload !== "object" || payload === null) {
6
16
  return undefined;
7
17
  }
8
18
 
9
19
  const payloadPayload =
10
20
  "payload" in payload && typeof payload.payload === "object" && payload.payload !== null
11
- ? payload.payload
21
+ ? (payload.payload as Record<string, unknown>)
12
22
  : undefined;
13
23
 
14
24
  let configLabelKey: string = key;
15
25
 
16
26
  if (key in payload && typeof payload[key as keyof typeof payload] === "string") {
17
27
  configLabelKey = payload[key as keyof typeof payload] as string;
18
- } else if (
19
- payloadPayload &&
20
- key in payloadPayload &&
21
- typeof payloadPayload[key as keyof typeof payloadPayload] === "string"
22
- ) {
23
- configLabelKey = payloadPayload[key as keyof typeof payloadPayload] as string;
28
+ } else if (payloadPayload && key in payloadPayload && typeof payloadPayload[key] === "string") {
29
+ configLabelKey = payloadPayload[key];
24
30
  }
25
31
 
26
32
  return configLabelKey in config ? config[configLabelKey] : config[key];
@@ -52,12 +52,12 @@ const barArgKey = {
52
52
  yAxis: "yAxis",
53
53
  } satisfies Record<string, BarArgKey>;
54
54
 
55
- export const barChartArgs = {
55
+ export const barChartArgs: ArgTypes = {
56
56
  ...categorizeArgs(barChartComponentArgs, barArgKey.barChart),
57
57
  ...categorizeArgs(xAxisArgs, barArgKey.xAxis),
58
58
  ...categorizeArgs(yAxisArgs, barArgKey.yAxis),
59
59
  ...categorizeArgs(barArgs, barArgKey.bar),
60
- } satisfies ArgTypes;
60
+ };
61
61
 
62
62
  /**
63
63
  * Line chart
@@ -78,12 +78,12 @@ const lineArgKey = {
78
78
  yAxis: "yAxis",
79
79
  } satisfies Record<string, LineArgKey>;
80
80
 
81
- export const lineChartArgs = {
81
+ export const lineChartArgs: ArgTypes = {
82
82
  ...categorizeArgs(lineChartComponentArgs, lineArgKey.lineChart),
83
83
  ...categorizeArgs(xAxisArgs, lineArgKey.xAxis),
84
84
  ...categorizeArgs(yAxisArgs, lineArgKey.yAxis),
85
85
  ...categorizeArgs(lineArgs, lineArgKey.line),
86
- } satisfies ArgTypes;
86
+ };
87
87
 
88
88
  /**
89
89
  * Area chart
@@ -104,12 +104,12 @@ export const areaArgKey = {
104
104
  yAxis: "yAxis",
105
105
  } satisfies Record<string, AreaArgKey>;
106
106
 
107
- export const areaChartArgs = {
107
+ export const areaChartArgs: ArgTypes = {
108
108
  ...categorizeArgs(areaChartComponentArgs, areaArgKey.areaChart),
109
109
  ...categorizeArgs(xAxisArgs, areaArgKey.xAxis),
110
110
  ...categorizeArgs(yAxisArgs, areaArgKey.yAxis),
111
111
  ...categorizeArgs(areaArgs, areaArgKey.area),
112
- } satisfies ArgTypes;
112
+ };
113
113
 
114
114
  /**
115
115
  * Pie chart
@@ -128,10 +128,10 @@ export const pieArgKey = {
128
128
  pieChart: "pieChart",
129
129
  } satisfies Record<string, PieArgKey>;
130
130
 
131
- export const pieChartArgs = {
131
+ export const pieChartArgs: ArgTypes = {
132
132
  ...categorizeArgs(pieChartComponentArgs, pieArgKey.pieChart),
133
133
  ...categorizeArgs(pieArgs, pieArgKey.pie),
134
- } satisfies ArgTypes;
134
+ };
135
135
 
136
136
  /**
137
137
  * RadialBar chart
@@ -150,10 +150,10 @@ export const radialBarArgKey = {
150
150
  radialBarChart: "radialBarChart",
151
151
  } satisfies Record<string, RadialBarArgKey>;
152
152
 
153
- export const radialBarChartArgs = {
153
+ export const radialBarChartArgs: ArgTypes = {
154
154
  ...categorizeArgs(radialBarChartComponentArgs, radialBarArgKey.radialBarChart),
155
155
  ...categorizeArgs(radialBarArgs, radialBarArgKey.radialBar),
156
- } satisfies ArgTypes;
156
+ };
157
157
 
158
158
  /**
159
159
  * Radar chart
@@ -172,7 +172,7 @@ export const radarArgKey = {
172
172
  radarChart: "radarChart",
173
173
  } satisfies Record<string, RadarArgKey>;
174
174
 
175
- export const radarChartArgs = {
175
+ export const radarChartArgs: ArgTypes = {
176
176
  ...categorizeArgs(radarChartComponentArgs, radarArgKey.radarChart),
177
177
  ...categorizeArgs(radarArgs, radarArgKey.radar),
178
- } satisfies ArgTypes;
178
+ };
@@ -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";
@@ -0,0 +1,56 @@
1
+ import type {
2
+ DraggableSyntheticListeners,
3
+ DragOverlayProps,
4
+ DropAnimation,
5
+ UseDraggableArguments,
6
+ } from "@dnd-kit/core";
7
+ import type { CSSProperties, ReactNode, Ref } from "react";
8
+ import { type Transform } from "@dnd-kit/utilities";
9
+
10
+ export enum DraggableAxis {
11
+ All,
12
+ Vertical,
13
+ Horizontal,
14
+ }
15
+
16
+ export type DraggableHandleElement = JSX.Element | null;
17
+
18
+ export type DraggableActionsArgs = {
19
+ draggable: {
20
+ ref: Ref<HTMLElement> | undefined;
21
+ listeners: DraggableSyntheticListeners;
22
+ };
23
+ };
24
+
25
+ type BaseDraggableProps = Partial<{
26
+ axis: DraggableAxis;
27
+ style: CSSProperties;
28
+ handle: DraggableHandleElement;
29
+ actions: (args: Partial<DraggableActionsArgs>) => ReactNode;
30
+ }> &
31
+ React.HTMLAttributes<HTMLDivElement>;
32
+
33
+ export type DraggableProps = BaseDraggableProps & UseDraggableArguments;
34
+
35
+ export type DraggableRootProps = BaseDraggableProps &
36
+ Partial<{
37
+ isDragOverlay: boolean;
38
+
39
+ isDragging: boolean;
40
+ listeners: DraggableSyntheticListeners;
41
+ transform: Transform | null;
42
+ activatorNodeRef: Ref<HTMLElement>;
43
+ }>;
44
+
45
+ export type DraggableActionProps = React.HTMLAttributes<HTMLButtonElement> & {
46
+ active?: Partial<{
47
+ fill: string;
48
+ background: string;
49
+ }>;
50
+ cursor?: CSSProperties["cursor"];
51
+ };
52
+
53
+ export type DraggableOverlayProps = {
54
+ axis?: DraggableRootProps["axis"];
55
+ dropAnimation?: DropAnimation | null;
56
+ } & DragOverlayProps;
@@ -0,0 +1,86 @@
1
+ import type { Modifiers, UniqueIdentifier } from "@dnd-kit/core";
2
+ import { useState } from "react";
3
+ import {
4
+ closestCenter,
5
+ closestCorners,
6
+ DndContext,
7
+ pointerWithin,
8
+ rectIntersection,
9
+ } from "@dnd-kit/core";
10
+ import { Draggable } from "../Draggable";
11
+ import { Droppable } from "./Droppable";
12
+
13
+ type CollisionDetectionType =
14
+ | "rectIntersection"
15
+ | "closestCenter"
16
+ | "closestCorners"
17
+ | "pointerWithin";
18
+
19
+ const collisionDetectionAlgorithms = {
20
+ rectIntersection,
21
+ closestCenter,
22
+ closestCorners,
23
+ pointerWithin,
24
+ };
25
+
26
+ type DroppableExampleProps = {
27
+ collisionDetection?: CollisionDetectionType;
28
+ containers?: UniqueIdentifier[];
29
+ modifiers?: Modifiers;
30
+ };
31
+
32
+ export const DroppableExample = ({
33
+ containers = ["A"],
34
+ collisionDetection = "rectIntersection",
35
+ modifiers,
36
+ }: DroppableExampleProps) => {
37
+ const [isDragging, setIsDragging] = useState(false);
38
+ const [parentContainerId, setParentContainerId] = useState<UniqueIdentifier | null>(null);
39
+
40
+ const item = (
41
+ <Draggable
42
+ id="my-draggable"
43
+ className="w-fit border border-base-content rounded-md p-2 flex items-center gap-2 data-[draggable-active]:opacity-0"
44
+ >
45
+ Go ahead, drag me.
46
+ </Draggable>
47
+ );
48
+
49
+ return (
50
+ <DndContext
51
+ collisionDetection={collisionDetectionAlgorithms[collisionDetection]}
52
+ modifiers={parentContainerId !== null ? undefined : modifiers}
53
+ onDragStart={() => setIsDragging(true)}
54
+ onDragEnd={({ over }) => {
55
+ setParentContainerId(over ? over.id : null);
56
+ setIsDragging(false);
57
+ }}
58
+ onDragCancel={() => setIsDragging(false)}
59
+ >
60
+ <div className="flex gap-6 items-center">
61
+ <div className="my-10 w-52">{parentContainerId === null ? item : null}</div>
62
+ <div className="grid grid-cols-2 gap-6">
63
+ {containers.map((id) => (
64
+ <Droppable
65
+ key={id}
66
+ id={id}
67
+ isDragging={isDragging}
68
+ className="relative p-6 border border-base-300 rounded-md w-72 h-72 bg-base-200 box-border data-[draggable-active]:opacity-80 data-[draggable-over]:opacity-100 transition-opacity"
69
+ >
70
+ <div className="absolute bottom-6">Container {id}</div>
71
+ {parentContainerId === id ? item : null}
72
+ </Droppable>
73
+ ))}
74
+ </div>
75
+ </div>
76
+ <Draggable.Overlay />
77
+ </DndContext>
78
+ );
79
+ };
80
+
81
+ export const CollisionDetectionAlgorithmsDroppableExample = ({
82
+ collisionDetection,
83
+ ...props
84
+ }: DroppableExampleProps) => {
85
+ return <DroppableExample {...props} collisionDetection={collisionDetection} />;
86
+ };
@@ -0,0 +1,38 @@
1
+ "use client";
2
+
3
+ import { useDroppable } from "@dnd-kit/core";
4
+ import { cn } from "../../../utilities";
5
+ import { getDroppableClasses } from "./constants";
6
+ import { type DroppableProps } from "./types";
7
+
8
+ export const Droppable = ({
9
+ children,
10
+ id,
11
+ disabled,
12
+ data,
13
+ resizeObserverConfig,
14
+ isDragging,
15
+ className,
16
+ ...props
17
+ }: DroppableProps) => {
18
+ const { isOver, setNodeRef } = useDroppable({
19
+ id,
20
+ data,
21
+ disabled,
22
+ resizeObserverConfig,
23
+ });
24
+ const isEmpty = !children || undefined;
25
+
26
+ return (
27
+ <div
28
+ ref={setNodeRef}
29
+ className={cn(className, getDroppableClasses({ isDragging, isOver, isEmpty }))}
30
+ data-empty={isEmpty}
31
+ data-draggable-over={isOver || undefined}
32
+ data-draggable-active={isDragging || undefined}
33
+ {...props}
34
+ >
35
+ {children}
36
+ </div>
37
+ );
38
+ };
@@ -0,0 +1,15 @@
1
+ import { cva } from "../../../libs";
2
+
3
+ export const getDroppableClasses = cva("relative", {
4
+ variants: {
5
+ isDragging: {
6
+ true: "",
7
+ },
8
+ isOver: {
9
+ true: "",
10
+ },
11
+ isEmpty: {
12
+ true: "",
13
+ },
14
+ },
15
+ });
@@ -0,0 +1 @@
1
+ export { Droppable } from "./Droppable";
@@ -0,0 +1,7 @@
1
+ import { type UseDroppableArguments } from "@dnd-kit/core";
2
+
3
+ export type DroppableProps = Omit<React.HTMLAttributes<HTMLDivElement>, "id"> &
4
+ UseDroppableArguments &
5
+ Partial<{
6
+ isDragging: boolean;
7
+ }>;