import { z } from "zod";
import type { GenerativeUILibrary } from "../types";
import { fire } from "./dispatch";
const INTERACTIVE_DESCENDANT_SELECTOR =
'button, a, input, select, textarea, label, [role="button"], [role="link"], [role="checkbox"], [role="radio"], [role="switch"], [role="textbox"], [role="combobox"], [role="menuitem"]';
export const listVocabulary = {
ListView: {
description:
"A vertical list container. Wrap `ListViewItem` children as rows.",
properties: z.object({}),
render: ({ children }) =>
,
},
ListViewItem: {
description:
"A row inside a ListView. Carries `$action` to make the whole row clickable and keyboard-activatable.",
properties: z.object({}),
render: ({ $action, $dispatch, children }) => {
if (!$action || !$dispatch) {
return {children};
}
return (
{
const target = event.target as Element;
const hit = target.closest(INTERACTIVE_DESCENDANT_SELECTOR);
if (hit !== null && hit !== event.currentTarget) return;
fire($action, $dispatch);
}}
onKeyDown={(event) => {
if (event.key !== "Enter" && event.key !== " ") return;
const target = event.target as Element;
const hit = target.closest(INTERACTIVE_DESCENDANT_SELECTOR);
if (hit !== null && hit !== event.currentTarget) return;
if (event.key === " ") event.preventDefault();
fire($action, $dispatch);
}}
>
{children}
);
},
},
} satisfies GenerativeUILibrary;