Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 52 additions & 3 deletions src/hooks/useResizer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,18 @@ function createMockElement(): HTMLDivElement {
// Helper to create a PointerEvent with required properties
function createPointerEvent(
type: string,
options: { clientX?: number; clientY?: number; pointerId?: number } = {}
options: {
clientX?: number;
clientY?: number;
pointerId?: number;
pointerType?: string;
} = {}
): PointerEvent {
return new PointerEvent(type, {
clientX: options.clientX ?? 0,
clientY: options.clientY ?? 0,
pointerId: options.pointerId ?? 1,
pointerType: options.pointerType ?? 'mouse',
bubbles: true,
});
}
Expand Down Expand Up @@ -160,6 +166,7 @@ describe('useResizer', () => {
expect(onResizeStart).toHaveBeenCalledWith({
sizes: [300, 700],
source: 'pointer',
pointerType: 'mouse',
originalEvent: expect.any(PointerEvent),
});
});
Expand Down Expand Up @@ -284,6 +291,7 @@ describe('useResizer', () => {
expect(onResizeEnd).toHaveBeenCalledWith([300, 700], {
sizes: [300, 700],
source: 'pointer',
pointerType: 'mouse',
});
});

Expand Down Expand Up @@ -590,7 +598,7 @@ describe('useResizer', () => {
expect(mockElement.setPointerCapture).toHaveBeenCalledWith(42);
});

it('handles touch input via pointer events', () => {
it('handles touch input via pointer events and passes pointerType', () => {
const mockElement = createMockElement();
const onResizeStart = vi.fn();
const { result } = renderHook(() =>
Expand Down Expand Up @@ -619,18 +627,21 @@ describe('useResizer', () => {
expect(onResizeStart).toHaveBeenCalledWith({
sizes: [300, 700],
source: 'pointer',
pointerType: 'touch',
originalEvent: expect.any(PointerEvent),
});
});

it('handles pen input via pointer events', () => {
it('handles pen input via pointer events and passes pointerType', () => {
const mockElement = createMockElement();
const onResizeStart = vi.fn();
const { result } = renderHook(() =>
useResizer({
direction: 'horizontal',
sizes: [300, 700],
minSizes: [100, 100],
maxSizes: [500, 900],
onResizeStart,
})
);

Expand All @@ -647,6 +658,44 @@ describe('useResizer', () => {
});

expect(result.current.isDragging).toBe(true);
expect(onResizeStart).toHaveBeenCalledWith({
sizes: [300, 700],
source: 'pointer',
pointerType: 'pen',
originalEvent: expect.any(PointerEvent),
});
});

it('passes mouse pointerType by default', () => {
const mockElement = createMockElement();
const onResizeStart = vi.fn();
const { result } = renderHook(() =>
useResizer({
direction: 'horizontal',
sizes: [300, 700],
minSizes: [100, 100],
maxSizes: [500, 900],
onResizeStart,
})
);

act(() => {
const pointerDown = result.current.handlePointerDown(0);
const event = createMockReactPointerEvent(mockElement, {
clientX: 300,
clientY: 0,
pointerId: 1,
pointerType: 'mouse',
});
pointerDown(event);
});

expect(onResizeStart).toHaveBeenCalledWith({
sizes: [300, 700],
source: 'pointer',
pointerType: 'mouse',
originalEvent: expect.any(PointerEvent),
});
});

it('ignores pointer events from non-captured pointers (multi-touch)', () => {
Expand Down
12 changes: 10 additions & 2 deletions src/hooks/useResizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export function useResizer(options: UseResizerOptions): UseResizerResult {
startPosition: number;
startSizes: number[];
pointerId: number;
pointerType: 'mouse' | 'touch' | 'pen';
element: HTMLElement | null;
} | null>(null);

Expand Down Expand Up @@ -111,7 +112,8 @@ export function useResizer(options: UseResizerOptions): UseResizerResult {
(clientX: number, clientY: number) => {
if (!dragStateRef.current || !mountedRef.current) return;

const { dividerIndex, startPosition, startSizes } = dragStateRef.current;
const { dividerIndex, startPosition, startSizes, pointerType } =
dragStateRef.current;
const currentPosition = direction === 'horizontal' ? clientX : clientY;

let delta = currentPosition - startPosition;
Expand Down Expand Up @@ -142,6 +144,7 @@ export function useResizer(options: UseResizerOptions): UseResizerResult {
onResize(newSizes, {
sizes: newSizes,
source: 'pointer',
pointerType,
});
}
},
Expand Down Expand Up @@ -186,7 +189,7 @@ export function useResizer(options: UseResizerOptions): UseResizerResult {
}

// Release pointer capture
const { element, pointerId } = dragStateRef.current;
const { element, pointerId, pointerType } = dragStateRef.current;
if (element?.hasPointerCapture?.(pointerId)) {
element.releasePointerCapture(pointerId);
}
Expand All @@ -207,6 +210,7 @@ export function useResizer(options: UseResizerOptions): UseResizerResult {
latestOnResizeEnd(latestSizes, {
sizes: latestSizes,
source: 'pointer',
pointerType,
});
}

Expand All @@ -223,11 +227,14 @@ export function useResizer(options: UseResizerOptions): UseResizerResult {
// Capture the pointer to receive all pointer events even if pointer leaves element
element.setPointerCapture(e.pointerId);

const pointerType = e.pointerType as 'mouse' | 'touch' | 'pen';

dragStateRef.current = {
dividerIndex,
startPosition,
startSizes: currentSizes,
pointerId: e.pointerId,
pointerType,
element,
};

Expand All @@ -237,6 +244,7 @@ export function useResizer(options: UseResizerOptions): UseResizerResult {
onResizeStart({
sizes: currentSizes,
source: 'pointer',
pointerType,
originalEvent: e.nativeEvent,
});
}
Expand Down
2 changes: 2 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export type Size = string | number;
export interface ResizeEvent {
sizes: number[];
source: 'pointer' | 'keyboard';
/** The type of pointer that initiated the resize (mouse, touch, or pen) */
pointerType?: 'mouse' | 'touch' | 'pen';
originalEvent?: PointerEvent | KeyboardEvent;
}

Expand Down