|
| 1 | +<!-- AUTO-GENERATED FROM src/agent-html/schema/prompt.md --> |
1 | 2 | # Agent-HTML Grammar |
2 | 3 |
|
3 | | -Source of truth lives in: |
| 4 | +# Gallery Preview DSL |
4 | 5 |
|
5 | | -- `src/agent-html/schema/prompt.md` |
| 6 | +## Contract |
6 | 7 |
|
7 | | -Use that file when you need the full grammar. |
8 | | - |
9 | | -## Core Contract |
10 | | - |
11 | | -- Output only `agent-html` DSL. |
| 8 | +- Output only Gallery Preview DSL. |
12 | 9 | - Use JSX-like XML tags with `PascalCase`. |
13 | 10 | - Root must be `<Page>`. |
14 | | -- Attr values must be quoted scalars. |
| 11 | +- Attribute values must be quoted scalars. |
| 12 | + Example: `columns="2"`, `value="82"`. |
15 | 13 | - Do not use `class`, `className`, `style`, imports, fragments, hooks, JS expressions, or raw HTML. |
16 | 14 | - Do not use unknown tags or unknown attrs. |
17 | 15 | - Do not put bare text directly under `Page`, `Stack`, `Cluster`, or `Grid`. |
18 | 16 |
|
19 | | -## Layout |
20 | | - |
21 | | -- `Page:title=string, gap?="xs|sm|md|lg"` |
22 | | -- `Stack:gap?="xs|sm|md|lg"` |
23 | | -- `Cluster:gap?="xs|sm|md|lg", justify?="start|center|end|between", wrap?="true|false"` |
24 | | -- `Grid:columns?="1|2|3|4", gap?="xs|sm|md|lg"` |
25 | | - |
26 | | -## Supported UI Tags |
27 | | - |
28 | | -- `Accordion`, `AccordionItem`, `AccordionTrigger`, `AccordionContent` |
29 | | -- `Alert`, `AlertTitle`, `AlertDescription`, `AlertAction` |
30 | | -- `AspectRatio` |
31 | | -- `Badge` |
32 | | -- `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardAction`, `CardContent`, `CardFooter` |
33 | | -- `Carousel`, `CarouselContent`, `CarouselItem`, `CarouselPrevious`, `CarouselNext` |
34 | | -- `Progress` |
35 | | -- `Separator` |
36 | | -- `Table`, `TableCaption`, `TableHeader`, `TableBody`, `TableFooter`, `TableRow`, `TableHead`, `TableCell` |
37 | | -- `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent` |
38 | | -- `Chart`, `ChartSeries`, `ChartTooltip` |
39 | | -- `Icon` |
40 | | - |
41 | 17 | ## Defaults |
42 | 18 |
|
43 | | -- `Page gap="md"` |
44 | | -- `Stack gap="md"` |
45 | | -- `Cluster gap="md" justify="start" wrap="true"` |
46 | | -- `Grid columns="2" gap="md"` |
| 19 | +- `Cluster justify="start" wrap="true"` |
| 20 | +- `Grid columns="2"` |
47 | 21 | - `Alert variant="default"` |
48 | 22 | - `Card size="default"` |
49 | 23 | - `Carousel orientation="horizontal"` |
50 | 24 | - `Separator orientation="horizontal"` |
51 | 25 | - `Tabs orientation="horizontal"` |
52 | 26 | - `ChartTooltip hideLabel="false"` |
53 | 27 |
|
54 | | -## Icon |
| 28 | +## Layout |
| 29 | + |
| 30 | +- `Page:title=string -> Layout | UI` |
| 31 | +- `Stack -> Layout | UI` |
| 32 | +- `Cluster:justify?="start|center|end|between", wrap?="true|false" -> Layout | UI` |
| 33 | +- `Grid:columns?="1|2|3|4" -> Layout | UI` |
| 34 | + |
| 35 | +## UI |
| 36 | + |
| 37 | +- `Accordion:type="single|multiple" -> AccordionItem+` |
| 38 | +- `AccordionItem:value?=string, disabled?="true|false" -> AccordionTrigger, AccordionContent` |
| 39 | +- `AccordionTrigger -> Text` |
| 40 | +- `AccordionContent -> Layout | UI | Text` |
| 41 | + |
| 42 | +- `Alert:variant?="default|destructive" -> Icon?, AlertTitle?, AlertDescription?, AlertAction?` |
| 43 | +- `AlertTitle -> Text` |
| 44 | +- `AlertDescription -> Text` |
| 45 | +- `AlertAction -> Layout | UI | Text` |
| 46 | + |
| 47 | +- `AspectRatio:ratio=number -> Layout | UI` |
| 48 | + |
| 49 | +- `Badge:variant?="default|secondary|destructive|outline|ghost|link" -> Text, Icon?` |
| 50 | + |
| 51 | +- `Card:size?="default|sm" -> CardHeader?, CardContent?, CardFooter?` |
| 52 | +- `CardHeader -> CardTitle?, CardDescription?, CardAction?` |
| 53 | +- `CardTitle -> Text` |
| 54 | +- `CardDescription -> Text` |
| 55 | +- `CardAction -> Layout | UI | Text` |
| 56 | +- `CardContent -> Layout | UI | Text` |
| 57 | +- `CardFooter -> Layout | UI | Text` |
| 58 | + |
| 59 | +- `Carousel:orientation?="horizontal|vertical" -> CarouselContent, CarouselPrevious?, CarouselNext?` |
| 60 | +- `CarouselContent -> CarouselItem+` |
| 61 | +- `CarouselItem -> Layout | UI | Text` |
| 62 | +- `CarouselPrevious -> none` |
| 63 | +- `CarouselNext -> none` |
| 64 | + |
| 65 | +- `Progress:value=number -> none` |
| 66 | + |
| 67 | +- `Separator:orientation?="horizontal|vertical" -> none` |
| 68 | + |
| 69 | +- `Table -> TableCaption?, TableHeader?, TableBody?, TableFooter?` |
| 70 | +- `TableCaption -> Text` |
| 71 | +- `TableHeader -> TableRow+` |
| 72 | +- `TableBody -> TableRow+` |
| 73 | +- `TableFooter -> TableRow+` |
| 74 | +- `TableRow -> TableHead+ | TableCell+` |
| 75 | +- `TableHead -> Text` |
| 76 | +- `TableCell -> Layout | UI | Text` |
| 77 | + |
| 78 | +- `Tabs:orientation?="horizontal|vertical", defaultValue?=string -> TabsList, TabsContent+` |
| 79 | +- `TabsList -> TabsTrigger+` |
| 80 | +- `TabsTrigger:value=string, disabled?="true|false" -> Text, Icon?` |
| 81 | +- `TabsContent:value=string -> Layout | UI | Text` |
| 82 | + |
| 83 | +- `Chart:type="area|bar" -> ChartSeries+, ChartTooltip?` |
| 84 | +- `ChartSeries:key=string, label?=string` |
| 85 | +- `ChartTooltip:hideLabel?="true|false" -> none` |
55 | 86 |
|
56 | 87 | - `Icon:name=string -> none` |
57 | | -- Names use Lucide kebab-case names. |
58 | | -- Do not guess icon names. Use the icon search helper if unsure. |
| 88 | + |
| 89 | +## Canonical Example |
| 90 | + |
| 91 | +```xml |
| 92 | +<Page title="Gallery Preview"> |
| 93 | + <Stack> |
| 94 | + <Card> |
| 95 | + <CardHeader> |
| 96 | + <CardTitle>Controls</CardTitle> |
| 97 | + <CardDescription>Preview action and state tokens.</CardDescription> |
| 98 | + </CardHeader> |
| 99 | + <CardContent> |
| 100 | + <Tabs defaultValue="publish"> |
| 101 | + <TabsList> |
| 102 | + <TabsTrigger value="publish">Publish</TabsTrigger> |
| 103 | + <TabsTrigger value="review">Review</TabsTrigger> |
| 104 | + </TabsList> |
| 105 | + <TabsContent value="publish"> |
| 106 | + <Stack> |
| 107 | + <Badge variant="secondary">82%</Badge> |
| 108 | + <Progress value="82" /> |
| 109 | + </Stack> |
| 110 | + </TabsContent> |
| 111 | + <TabsContent value="review"> |
| 112 | + <Alert> |
| 113 | + <AlertTitle>Review queue</AlertTitle> |
| 114 | + <AlertDescription>5 items remain.</AlertDescription> |
| 115 | + </Alert> |
| 116 | + </TabsContent> |
| 117 | + </Tabs> |
| 118 | + </CardContent> |
| 119 | + </Card> |
| 120 | + |
| 121 | + <Grid columns="2"> |
| 122 | + <Card> |
| 123 | + <CardContent> |
| 124 | + <Accordion type="single"> |
| 125 | + <AccordionItem value="notes"> |
| 126 | + <AccordionTrigger>Migration notes</AccordionTrigger> |
| 127 | + <AccordionContent> |
| 128 | + <Badge variant="outline">Pending</Badge> |
| 129 | + </AccordionContent> |
| 130 | + </AccordionItem> |
| 131 | + </Accordion> |
| 132 | + </CardContent> |
| 133 | + </Card> |
| 134 | + |
| 135 | + <Card> |
| 136 | + <CardContent> |
| 137 | + <Table> |
| 138 | + <TableHeader> |
| 139 | + <TableRow> |
| 140 | + <TableHead>Signal</TableHead> |
| 141 | + <TableHead>State</TableHead> |
| 142 | + </TableRow> |
| 143 | + </TableHeader> |
| 144 | + <TableBody> |
| 145 | + <TableRow> |
| 146 | + <TableCell>Spacing</TableCell> |
| 147 | + <TableCell>Balanced</TableCell> |
| 148 | + </TableRow> |
| 149 | + </TableBody> |
| 150 | + </Table> |
| 151 | + </CardContent> |
| 152 | + </Card> |
| 153 | + </Grid> |
| 154 | + </Stack> |
| 155 | +</Page> |
| 156 | +``` |
| 157 | + |
| 158 | +## Never |
| 159 | + |
| 160 | +- No `<div>`, `<p>`, `<span>`, `<img>`, or raw HTML tags. |
| 161 | +- No `class`, `className`, or `style`. |
| 162 | +- No JSX expressions like `{50}` or `{16 / 9}`. |
| 163 | +- No unknown tags. |
| 164 | +- No `TabsPanel`. |
| 165 | +- No bare text under `Page`, `Stack`, `Cluster`, or `Grid`. |
0 commit comments