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;