refactor(dragdrop): generalize createBlockDragDrop<T extends { id: string }>
Removes the hard-typed TranscriptionBlockData constraint so JourneyEditor can reuse the pointer-drag module without importing transcription types. Selector contract (data-block-wrapper / data-drag-handle) unchanged. Adds type-regression guard test verified via tsc --noEmit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,33 @@
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { describe, it, expect, vi, expectTypeOf } from 'vitest';
|
||||
import { createBlockDragDrop } from './useBlockDragDrop.svelte';
|
||||
import type { TranscriptionBlockData } from '$lib/shared/types';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Type-regression guard: createBlockDragDrop must accept any T extends {id: string}
|
||||
// so JourneyEditor can reuse it without importing TranscriptionBlockData.
|
||||
// This test fails with "Expected 0 type arguments, but got 1" via tsc --noEmit
|
||||
// until the function is made generic.
|
||||
// ---------------------------------------------------------------------------
|
||||
describe('createBlockDragDrop — generic type guard', () => {
|
||||
it('accepts items shaped as { id: string; position: number } — not only TranscriptionBlockData', () => {
|
||||
type SimpleItem = { id: string; position: number };
|
||||
const items: SimpleItem[] = [
|
||||
{ id: 'item-1', position: 0 },
|
||||
{ id: 'item-2', position: 1 }
|
||||
];
|
||||
const onReorder = vi.fn();
|
||||
const dd = createBlockDragDrop<SimpleItem>({ getSortedBlocks: () => items, onReorder });
|
||||
// Verify the hook is functional with the new type — state reads must work
|
||||
expect(dd.draggedBlockId).toBeNull();
|
||||
expect(dd.dragOffsetY).toBe(0);
|
||||
});
|
||||
|
||||
it('TranscriptionBlockData caller still compiles — regression guard for existing transcription editor', () => {
|
||||
// If the generic constraint is wrong this line fails tsc --noEmit
|
||||
expectTypeOf(createBlockDragDrop<TranscriptionBlockData>).toBeFunction();
|
||||
});
|
||||
});
|
||||
|
||||
function makeBlock(id: string, sortOrder: number): TranscriptionBlockData {
|
||||
return {
|
||||
id,
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import type { TranscriptionBlockData } from '$lib/shared/types';
|
||||
|
||||
type Options = {
|
||||
getSortedBlocks: () => TranscriptionBlockData[];
|
||||
type Options<T extends { id: string }> = {
|
||||
getSortedBlocks: () => T[];
|
||||
onReorder: (blockIds: string[]) => void;
|
||||
};
|
||||
|
||||
export function createBlockDragDrop({ getSortedBlocks, onReorder }: Options) {
|
||||
export function createBlockDragDrop<T extends { id: string }>({
|
||||
getSortedBlocks,
|
||||
onReorder
|
||||
}: Options<T>) {
|
||||
let draggedBlockId = $state<string | null>(null);
|
||||
let dropTargetIdx = $state<number | null>(null);
|
||||
let dragOffsetY = $state(0);
|
||||
|
||||
Reference in New Issue
Block a user