From a267754f8fed781cb97d3d5421d07b9887ad0a43 Mon Sep 17 00:00:00 2001 From: mptyl Date: Sun, 28 Jun 2026 12:25:50 +0200 Subject: [PATCH] feat(frontend): F1 widgets (select/info/freetext) + reserved controls --- frontend/src/widgets/FreetextWidget.test.tsx | 10 ++++++++++ frontend/src/widgets/FreetextWidget.tsx | 12 ++++++++++++ frontend/src/widgets/InfoWidget.tsx | 5 +++++ frontend/src/widgets/ReservedControls.tsx | 7 +++++++ frontend/src/widgets/SelectWidget.test.tsx | 17 +++++++++++++++++ frontend/src/widgets/SelectWidget.tsx | 19 +++++++++++++++++++ frontend/src/widgets/index.ts | 6 ++++++ 7 files changed, 76 insertions(+) create mode 100644 frontend/src/widgets/FreetextWidget.test.tsx create mode 100644 frontend/src/widgets/FreetextWidget.tsx create mode 100644 frontend/src/widgets/InfoWidget.tsx create mode 100644 frontend/src/widgets/ReservedControls.tsx create mode 100644 frontend/src/widgets/SelectWidget.test.tsx create mode 100644 frontend/src/widgets/SelectWidget.tsx create mode 100644 frontend/src/widgets/index.ts diff --git a/frontend/src/widgets/FreetextWidget.test.tsx b/frontend/src/widgets/FreetextWidget.test.tsx new file mode 100644 index 00000000..64db4be6 --- /dev/null +++ b/frontend/src/widgets/FreetextWidget.test.tsx @@ -0,0 +1,10 @@ +import { render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { FreetextWidget } from "./FreetextWidget"; +test("submits typed text", async () => { + const onRespond = vi.fn(); + render(); + await userEvent.type(screen.getByRole("textbox"), "ciao"); + await userEvent.click(screen.getByRole("button", { name: /invia/i })); + expect(onRespond).toHaveBeenCalledWith({ id: "u1", kind: "freetext", text: "ciao" }); +}); diff --git a/frontend/src/widgets/FreetextWidget.tsx b/frontend/src/widgets/FreetextWidget.tsx new file mode 100644 index 00000000..178c4844 --- /dev/null +++ b/frontend/src/widgets/FreetextWidget.tsx @@ -0,0 +1,12 @@ +import { useState } from "react"; +import type { WidgetProps } from "./types"; +export function FreetextWidget({ descriptor, onRespond }: WidgetProps) { + const [text, setText] = useState(""); + return ( +
+ {descriptor.title &&

{descriptor.title}

} +