feat: release design system engine, studio and component contracts

This commit is contained in:
Clintchiz committed 2026-10-19 13:09:03 +05:30
1 parent ff1065fb27
commit 3943b946d6
693 files changed
+175546 -3894

No files matched your search

+60 -13
View File
@@ -56,7 +56,8 @@ function fixture(overrides: Partial<DndManagerOptions> = {}) {
instances,
move: (code: string) => listeners.dragmove!({ nativeEvent: { code } }),
start: (id: string) => listeners.dragstart!(event(id)),
end: (id: string, target?: { id: string }) => listeners.dragend!({ ...event(id), operation: { ...event(id).operation, target } }),
end: (id: string, target?: { id: string }) =>
listeners.dragend!({ ...event(id), operation: { ...event(id).operation, target } }),
over: (target: { id?: string; group?: string; index?: number }) => {
let prevented = false;
listeners.dragover!({
@@ -97,10 +98,26 @@ test("late drop resolution cannot clear or announce a newer gesture", async () =
test("keyboard candidates stay in the requested geometric row or column", () => {
const f = fixture();
const element = (left: number, top: number, right: number, bottom: number) => ({ getBoundingClientRect: () => ({ left, top, right, bottom }) }) as HTMLElement;
f.manager.registerSortable({ id: "source", group: "a", index: 0, element: element(0, 100, 100, 150) });
f.manager.registerDropZone({ id: "right", group: "b", index: 0, element: element(110, 100, 200, 160) });
f.manager.registerSortable({ id: "above", group: "c", index: 0, element: element(0, 0, 300, 90) });
const element = (left: number, top: number, right: number, bottom: number) =>
({ getBoundingClientRect: () => ({ left, top, right, bottom }) }) as HTMLElement;
f.manager.registerSortable({
id: "source",
group: "a",
index: 0,
element: element(0, 100, 100, 150),
});
f.manager.registerDropZone({
id: "right",
group: "b",
index: 0,
element: element(110, 100, 200, 160),
});
f.manager.registerSortable({
id: "above",
group: "c",
index: 0,
element: element(0, 0, 300, 90),
});
const source = { id: "source", type: "text" };
f.start("source");
f.move("ArrowRight");
@@ -117,10 +134,32 @@ test("keyboard candidates stay in the requested geometric row or column", () =>
test("collision candidates exclude overlapping ancestors and invalid destinations before sorting", () => {
const f = fixture({ accept: (_ids, to) => to.group !== "blocked" });
const child = {} as HTMLElement;
f.manager.registerSortable({ id: "child", group: "content", index: 0, element: child, type: "text" });
f.manager.registerSortable({ id: "parent", group: "root", index: 0, element: { contains: (element: unknown) => element === child } as HTMLElement });
f.manager.registerSortable({ id: "sibling", group: "content", index: 1, element: {} as HTMLElement, accepts: ["text"] });
f.manager.registerSortable({ id: "invalid", group: "blocked", index: 0, element: {} as HTMLElement });
f.manager.registerSortable({
id: "child",
group: "content",
index: 0,
element: child,
type: "text",
});
f.manager.registerSortable({
id: "parent",
group: "root",
index: 0,
element: { contains: (element: unknown) => element === child } as HTMLElement,
});
f.manager.registerSortable({
id: "sibling",
group: "content",
index: 1,
element: {} as HTMLElement,
accepts: ["text"],
});
f.manager.registerSortable({
id: "invalid",
group: "blocked",
index: 0,
element: {} as HTMLElement,
});
const source = { id: "child", type: "text" };
expect(f.instances[1]!.input.accept(source)).toBe(false);
expect(f.instances[2]!.input.accept(source)).toBe(true);
@@ -131,7 +170,12 @@ test("collision candidates exclude overlapping ancestors and invalid destination
test("empty drop zones use explicit locations for acceptance and commit", async () => {
const commits: unknown[] = [];
const f = fixture({ accept: (_ids, to) => to.group === "empty", onMoveIntent: intent => { commits.push(intent.to); } });
const f = fixture({
accept: (_ids, to) => to.group === "empty",
onMoveIntent: (intent) => {
commits.push(intent.to);
},
});
const registration = { id: "zone", group: "empty", index: 0, element: {} as HTMLElement };
const cleanup = f.manager.registerDropZone(registration);
f.start("block");
@@ -144,15 +188,18 @@ test("empty drop zones use explicit locations for acceptance and commit", async
f.manager.registerDropZone(registration);
cleanup();
expect(() => f.manager.registerDropZone(registration)).toThrow("Duplicate");
f.manager.destroy(); f.manager.destroy();
expect(f.instances.map(instance => instance.destroyed)).toEqual([1, 1]);
f.manager.destroy();
f.manager.destroy();
expect(f.instances.map((instance) => instance.destroyed)).toEqual([1, 1]);
expect(() => f.manager.registerDropZone(registration)).toThrow("destruction");
});
test("invalid drop zone indices are rejected before backend registration", () => {
const f = fixture();
for (const index of [-1, 0.5, Infinity, Number.MAX_SAFE_INTEGER + 1]) {
expect(() => f.manager.registerDropZone({ id: "zone", group: "empty", index, element: {} as HTMLElement })).toThrow("index");
expect(() =>
f.manager.registerDropZone({ id: "zone", group: "empty", index, element: {} as HTMLElement }),
).toThrow("index");
}
expect(f.instances).toEqual([]);
});