Skip to content

Commit 8c4c2cc

Browse files
authored
Merge pull request #79 from kimuraz/dev
2.1.2
2 parents 3b1c6af + d89e9cd commit 8c4c2cc

File tree

8 files changed

+179
-48
lines changed

8 files changed

+179
-48
lines changed

docs/guide/composables/components/DemoUseDragAndResize.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<script setup lang="ts">
22
import { nextTick, onMounted, ref } from 'vue';
3-
import { useInteractContext, useDraggable, useResizable } from 'vue-interact';
3+
import { useInteractContext, useDraggable, useResizable } from '../../../../src';
44
55
const interactableTarget = ref(null);
66
77
const context = useInteractContext(interactableTarget);
88
const { init, position } = useDraggable(context);
9-
const { init: initResize, resizeData } = useResizable(context);
9+
const { init: initResize, resizeData } = useResizable(context, {});
1010
1111
onMounted(() => {
1212
nextTick(() => {

docs/guide/composables/components/DemoUseDraggable.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
22
import { nextTick, onMounted, ref } from 'vue';
3-
import { useInteractContext, useDraggable } from 'vue-interact';
3+
import { useInteractContext, useDraggable } from '../../../../src';
44
55
const interactableTarget = ref(null);
66

docs/guide/composables/components/DemoUseResizable.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
22
import { nextTick, onMounted, ref } from 'vue';
3-
import { useInteractContext, useResizable } from 'vue-interact';
3+
import { useInteractContext, useResizable } from '../../../../src';
44
55
const interactableTarget = ref(null);
66

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "vue-interact",
33
"description": "Interact.js wrapper for VueJS",
4-
"version": "2.1.1",
4+
"version": "2.1.2",
55
"author": "Kimura <joseduardo.kimura@gmail.com>",
66
"private": false,
77
"type": "module",

src/composables/__tests__/useDraggable.test.ts

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
11
import { ref } from 'vue';
22
import useDraggable from '../useDraggable';
33
import type { InteractContext } from '../useInteractContext';
4+
import type {
5+
DraggableOptions,
6+
DragEvent,
7+
} from '@interactjs/actions/drag/plugin';
48

59
describe('useDraggable', () => {
610
let context: InteractContext;
711
let draggableMock: jest.Mock;
12+
let setMock: jest.Mock;
813

914
beforeEach(() => {
1015
draggableMock = jest.fn();
16+
setMock = jest.fn();
1117
context = {
12-
interactable: ref({ draggable: draggableMock } as any),
18+
interactable: ref({
19+
draggable: draggableMock,
20+
set: setMock,
21+
target: document.createElement('div'),
22+
} as any),
1323
interact: {} as any,
1424
position: ref({ x: 0, y: 0 }),
1525
size: ref({ width: 0, height: 0 }),
@@ -27,6 +37,24 @@ describe('useDraggable', () => {
2737
expect(typeof options.listeners.end).toBe('function');
2838
});
2939

40+
it('draggableOptions getter should return merged initial options', () => {
41+
const initialOpts: DraggableOptions = {
42+
inertia: { enabled: true },
43+
autoScroll: { enabled: true },
44+
};
45+
const { init, draggableOptions } = useDraggable(context, initialOpts);
46+
init();
47+
48+
const currentOptions = draggableOptions.value;
49+
expect(currentOptions.inertia).toEqual(initialOpts.inertia);
50+
expect(currentOptions.autoScroll).toEqual(initialOpts.autoScroll);
51+
expect(currentOptions.listeners).toBeDefined();
52+
const listeners = currentOptions.listeners as any;
53+
expect(typeof listeners.start).toBe('function');
54+
expect(typeof listeners.move).toBe('function');
55+
expect(typeof listeners.end).toBe('function');
56+
});
57+
3058
it('should handle drag events correctly', () => {
3159
const { init, isDragging, position } = useDraggable(context);
3260
init();
@@ -46,20 +74,49 @@ describe('useDraggable', () => {
4674
expect(isDragging.value).toBe(false);
4775
});
4876

49-
it('should call interactable.set when draggableOptions are set', () => {
50-
const setMock = jest.fn();
51-
context.interactable.value = {
52-
draggable: draggableMock,
53-
set: setMock,
54-
} as any;
77+
it('draggableOptions setter should update options and call interactable.set correctly', () => {
78+
const { init, draggableOptions } = useDraggable(context, {
79+
lockAxis: 'x',
80+
});
81+
init();
5582

56-
const { draggableOptions } = useDraggable(context);
83+
const newSpecificOptions: DraggableOptions = {
84+
inertia: { resistance: 10, enabled: true },
85+
autoScroll: {
86+
enabled: true,
87+
container: document.createElement('div'),
88+
},
89+
cursorChecker: () => 'grabbing',
90+
};
5791

58-
const newOptions = { enabled: false };
59-
draggableOptions.value = newOptions;
92+
draggableOptions.value = newSpecificOptions;
6093

6194
expect(setMock).toHaveBeenCalledTimes(1);
62-
expect(setMock).toHaveBeenCalledWith(newOptions);
95+
expect(setMock).toHaveBeenCalledWith({
96+
drag: expect.objectContaining({
97+
inertia: newSpecificOptions.inertia,
98+
autoScroll: newSpecificOptions.autoScroll,
99+
cursorChecker: newSpecificOptions.cursorChecker,
100+
listeners: expect.objectContaining({
101+
start: expect.any(Function),
102+
move: expect.any(Function),
103+
end: expect.any(Function),
104+
}),
105+
}),
106+
});
107+
108+
const updatedOptions = draggableOptions.value;
109+
expect(updatedOptions.inertia).toEqual(newSpecificOptions.inertia);
110+
expect(updatedOptions.autoScroll).toEqual(
111+
newSpecificOptions.autoScroll,
112+
);
113+
expect(updatedOptions.cursorChecker).toEqual(
114+
newSpecificOptions.cursorChecker,
115+
);
116+
expect(updatedOptions.lockAxis).toBeUndefined();
117+
expect(updatedOptions.listeners).toBeDefined();
118+
const listeners = updatedOptions.listeners as any;
119+
expect(typeof listeners.start).toBe('function');
63120
});
64121

65122
it('init throws when context.interactable.value is null', () => {

src/composables/__tests__/useResizable.test.ts

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,46 @@ describe('useResizable', () => {
5454
expect(options.listeners).toBeDefined();
5555
});
5656

57+
it('resizableOptions getter should return merged initial options', () => {
58+
const initialOpts: ResizableOptions = {
59+
inertia: { enabled: true },
60+
edges: { left: false, right: true, bottom: false, top: true },
61+
};
62+
const { init, resizableOptions } = useResizable(context, initialOpts);
63+
init();
64+
65+
const currentOptions = resizableOptions.value;
66+
expect(currentOptions.inertia).toEqual(initialOpts.inertia);
67+
expect(currentOptions.edges).toEqual(initialOpts.edges);
68+
expect(currentOptions.listeners).toBeDefined();
69+
});
70+
71+
it('resizableOptions setter should call interactable.set and update options', () => {
72+
const { init, resizableOptions } = useResizable(context, {});
73+
const mockResizableInteractable = {
74+
set: jest.fn(),
75+
};
76+
resizableMock.mockReturnValue(mockResizableInteractable);
77+
78+
init();
79+
80+
const newSpecificOptions: ResizableOptions = {
81+
inertia: { enabled: false },
82+
edges: { top: false, bottom: false, left: true, right: true },
83+
};
84+
85+
resizableOptions.value = newSpecificOptions;
86+
87+
expect(mockResizableInteractable.set).toHaveBeenCalledTimes(1);
88+
expect(mockResizableInteractable.set).toHaveBeenCalledWith({
89+
resize: expect.objectContaining(newSpecificOptions),
90+
});
91+
const updatedOptions = resizableOptions.value;
92+
expect(updatedOptions.inertia).toEqual(newSpecificOptions.inertia);
93+
expect(updatedOptions.edges).toEqual(newSpecificOptions.edges);
94+
expect(updatedOptions.listeners).toBeDefined();
95+
});
96+
5797
it('should handle resize events correctly', () => {
5898
const { init, isResizing, position, resizeData } = useResizable(
5999
context,
@@ -139,7 +179,16 @@ describe('useResizable', () => {
139179

140180
expect(setMock).toHaveBeenCalledTimes(1);
141181
expect(setMock).toHaveBeenCalledWith(
142-
expect.objectContaining(newOptions),
182+
expect.objectContaining({
183+
resize: {
184+
listeners: expect.objectContaining({
185+
start: expect.any(Function),
186+
move: expect.any(Function),
187+
end: expect.any(Function),
188+
}),
189+
...newOptions,
190+
},
191+
}),
143192
);
144193
});
145194

src/composables/useDraggable.ts

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,9 @@ const useDraggable = (
1414
interactOptions: DraggableOptions = {},
1515
) => {
1616
const isDragging = ref<boolean>(false);
17+
const _interactOptions = ref<DraggableOptions>(interactOptions);
1718
const position = context.position;
1819

19-
const draggableOptions = computed<DraggableOptions>({
20-
get: () => ({
21-
listeners: {
22-
start: onDragStart,
23-
move: onDragMove,
24-
end: onDragEnd,
25-
},
26-
...interactOptions,
27-
}),
28-
set: (value) => {
29-
interactOptions = value;
30-
(context.interactable.value as Interact.Interactable).set(value);
31-
},
32-
});
33-
3420
const onDragStart = (event: Interact.DragEvent) => {
3521
isDragging.value = true;
3622
};
@@ -46,6 +32,28 @@ const useDraggable = (
4632
isDragging.value = false;
4733
};
4834

35+
const staticListeners = {
36+
start: onDragStart,
37+
move: onDragMove,
38+
end: onDragEnd,
39+
};
40+
41+
const draggableOptions = computed<DraggableOptions>({
42+
get: () => ({
43+
listeners: staticListeners,
44+
..._interactOptions.value,
45+
}),
46+
set: (value) => {
47+
_interactOptions.value = value;
48+
(context.interactable.value as Interact.Interactable).set({
49+
drag: {
50+
listeners: staticListeners,
51+
..._interactOptions.value,
52+
},
53+
});
54+
},
55+
});
56+
4957
const init = () => {
5058
if (!context.interactable.value) {
5159
throw new Error('Interactable context is not set');

src/composables/useResizable.ts

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,14 @@ import { InteractContext } from './useInteractContext';
66

77
const useResizable = (
88
context: InteractContext,
9-
interactOptions: ResizableOptions,
9+
interactOptions: ResizableOptions = {},
1010
) => {
1111
const isResizing = ref<boolean>(false);
1212
const position = context.position;
1313
const resizeData = context.size;
14+
const _interactOptions = ref<ResizableOptions>(interactOptions);
15+
1416
let resizable: Interact.Interactable;
15-
const resizableOptions = computed<ResizableOptions>({
16-
get: () => ({
17-
edges: { left: true, right: true, bottom: true, top: true },
18-
listeners: {
19-
start: onResizeStart,
20-
move: onResizeMove,
21-
end: onResizeEnd,
22-
},
23-
...interactOptions,
24-
}),
25-
set: (value) => {
26-
interactOptions = value;
27-
resizable.set(value);
28-
},
29-
});
3017

3118
const onResizeStart = (event: Interact.ResizeEvent) => {
3219
isResizing.value = true;
@@ -55,6 +42,36 @@ const useResizable = (
5542
isResizing.value = false;
5643
};
5744

45+
const staticListeners = {
46+
start: onResizeStart,
47+
move: onResizeMove,
48+
end: onResizeEnd,
49+
};
50+
const defaultEdges = {
51+
left: true,
52+
right: true,
53+
bottom: true,
54+
top: true,
55+
};
56+
57+
const resizableOptions = computed<ResizableOptions>({
58+
get: () => ({
59+
edges: { ...defaultEdges },
60+
listeners: staticListeners,
61+
..._interactOptions.value,
62+
}),
63+
set: (value) => {
64+
_interactOptions.value = value;
65+
resizable.set({
66+
resize: {
67+
edges: { ...defaultEdges },
68+
listeners: staticListeners,
69+
..._interactOptions.value,
70+
},
71+
});
72+
},
73+
});
74+
5875
const init = () => {
5976
if (!context.interactable.value) {
6077
throw new Error('Interactable context is not set');

0 commit comments

Comments
 (0)