Skip to content

Commit fe0bdd8

Browse files
committed
feat: add missing shadcn components, normalize style profiles, and add gallery inspector metadata
This commit: 1. Adds dropdown-menu and popover to required shadcn runtime components 2. Implements normalizeStyleProfile to handle default style profile values 3. Exports normalizeStyleProfile from core package and re-exports it from ahtml core entrypoint 4. Updates style profile handling in CLI storage and request handlers 5. Adds full typography, color, and CSS variable map defaults to type definitions and tests 6. Adds renderer metadata props (render kind, source, and path) to rendered components 7. Adds popover and dropdown-menu component implementations to template fixtures 8. Updates all test snapshots and test data to match new default style values
1 parent eb46590 commit fe0bdd8

25 files changed

Lines changed: 8061 additions & 666 deletions

packages/ahtml/src/cli/cli-test-helpers.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,9 +658,23 @@ function createCustomStyleProfile() {
658658
accent: "#dff5f2",
659659
accentForeground: "#134e4a",
660660
destructive: "#be123c",
661+
destructiveForeground: "#fdf2f8",
661662
border: "#d9e2ec",
662663
input: "#bcccdc",
663664
ring: "#0f766e",
665+
chart1: "#0f766e",
666+
chart2: "#14b8a6",
667+
chart3: "#0ea5e9",
668+
chart4: "#6366f1",
669+
chart5: "#a855f7",
670+
sidebar: "#f7fbfb",
671+
sidebarForeground: "#1f2933",
672+
sidebarPrimary: "#0f766e",
673+
sidebarPrimaryForeground: "#f8fafc",
674+
sidebarAccent: "#dff5f2",
675+
sidebarAccentForeground: "#134e4a",
676+
sidebarBorder: "#d9e2ec",
677+
sidebarRing: "#0f766e",
664678
},
665679
dark: {
666680
background: "oklch(0.18 0.02 190)",
@@ -678,9 +692,23 @@ function createCustomStyleProfile() {
678692
accent: "oklch(0.32 0.03 190)",
679693
accentForeground: "oklch(0.96 0.01 190)",
680694
destructive: "oklch(0.62 0.2 20)",
695+
destructiveForeground: "oklch(0.96 0.01 190)",
681696
border: "oklch(1 0 0 / 12%)",
682697
input: "oklch(1 0 0 / 18%)",
683698
ring: "oklch(0.74 0.11 190)",
699+
chart1: "oklch(0.74 0.11 190)",
700+
chart2: "oklch(0.68 0.1 205)",
701+
chart3: "oklch(0.64 0.12 230)",
702+
chart4: "oklch(0.6 0.14 255)",
703+
chart5: "oklch(0.56 0.16 280)",
704+
sidebar: "oklch(0.22 0.02 190)",
705+
sidebarForeground: "oklch(0.96 0.01 190)",
706+
sidebarPrimary: "oklch(0.74 0.11 190)",
707+
sidebarPrimaryForeground: "oklch(0.2 0.02 190)",
708+
sidebarAccent: "oklch(0.32 0.03 190)",
709+
sidebarAccentForeground: "oklch(0.96 0.01 190)",
710+
sidebarBorder: "oklch(1 0 0 / 12%)",
711+
sidebarRing: "oklch(0.74 0.11 190)",
684712
},
685713
},
686714
radiusScale: {
@@ -697,6 +725,17 @@ function createCustomStyleProfile() {
697725
fontSans:
698726
'"Inter Variable", system-ui, "Helvetica Neue", Helvetica, Arial, sans-serif',
699727
fontHeading: "var(--font-sans)",
728+
fontSerif: 'ui-serif, Georgia, Cambria, "Times New Roman", Times, serif',
729+
fontMono:
730+
'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
731+
letterSpacing: "0em",
732+
spacing: "0.25rem",
733+
shadowColor: "oklch(0 0 0)",
734+
shadowOpacity: "0.1",
735+
shadowBlur: "3px",
736+
shadowSpread: "0px",
737+
shadowOffsetX: "0px",
738+
shadowOffsetY: "1px",
700739
},
701740
cssVariableMap: {
702741
background: "--background",
@@ -714,12 +753,36 @@ function createCustomStyleProfile() {
714753
accent: "--accent",
715754
accentForeground: "--accent-foreground",
716755
destructive: "--destructive",
756+
destructiveForeground: "--destructive-foreground",
717757
border: "--border",
718758
input: "--input",
719759
ring: "--ring",
760+
chart1: "--chart-1",
761+
chart2: "--chart-2",
762+
chart3: "--chart-3",
763+
chart4: "--chart-4",
764+
chart5: "--chart-5",
765+
sidebar: "--sidebar",
766+
sidebarForeground: "--sidebar-foreground",
767+
sidebarPrimary: "--sidebar-primary",
768+
sidebarPrimaryForeground: "--sidebar-primary-foreground",
769+
sidebarAccent: "--sidebar-accent",
770+
sidebarAccentForeground: "--sidebar-accent-foreground",
771+
sidebarBorder: "--sidebar-border",
772+
sidebarRing: "--sidebar-ring",
720773
radius: "--radius",
721774
fontSans: "--font-sans",
722775
fontHeading: "--font-heading",
776+
fontSerif: "--font-serif",
777+
fontMono: "--font-mono",
778+
letterSpacing: "--letter-spacing",
779+
spacing: "--spacing",
780+
shadowColor: "--shadow-color",
781+
shadowOpacity: "--shadow-opacity",
782+
shadowBlur: "--shadow-blur",
783+
shadowSpread: "--shadow-spread",
784+
shadowOffsetX: "--shadow-offset-x",
785+
shadowOffsetY: "--shadow-offset-y",
723786
},
724787
},
725788
componentStyle: {

packages/ahtml/src/cli/cli.gallery.heavy.test.ts

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -63,32 +63,39 @@ describe("agent-html CLI heavy gallery flows", () => {
6363
const response = await fetch(url)
6464
const body = await response.text()
6565

66-
expect(body).toContain("ahtml-gallery-hero-title")
66+
expect(body).toContain("ahtml-gallery-preset-select-row")
6767
expect(body).toContain(">report-default</")
68-
expect(body).toContain("AHTML Gallery")
69-
expect(body).toContain("Component gallery")
68+
expect(body).toContain("Gallery")
7069
expect(body).toContain("GitHub")
71-
expect(body).toContain("Current style id")
72-
expect(body).toContain("New Style Id")
73-
expect(body).toContain("Reset Draft")
74-
expect(body).toContain("Save Current Style")
70+
expect(body).toContain("Reset")
71+
expect(body).toContain("Save Style")
72+
expect(body).toContain("Colors")
7573
expect(body).toContain("Typography")
76-
expect(body).toContain("Treatments")
77-
expect(body).toContain("Persist")
78-
expect(body).toContain("Active style")
79-
expect(body).toContain("Preview mode")
74+
expect(body).toContain("Other")
75+
expect(body).toContain("Preset controls")
76+
expect(body).toContain("Editor theme mode")
77+
expect(body).toContain("Primary")
78+
expect(body).toContain("Secondary")
79+
expect(body).toContain("Border &amp; Input")
80+
expect(body).toContain("Read-only baseline preset")
81+
expect(body).toContain("Preview synced")
8082
expect(body).toContain('data-style-profile="report-default"')
8183
expect(body).toContain('class="ahtml-runtime-host ahtml-gallery-shell"')
8284
expect(body).toContain('data-gallery-frame="header"')
8385
expect(body).toContain('data-gallery-frame="controls"')
8486
expect(body).toContain('data-gallery-frame="preview"')
8587
expect(body).toContain("Controls")
86-
expect(body).toContain("Components")
87-
expect(body).toContain("Component gallery workbench")
88+
expect(body).toContain("Cards")
89+
expect(body).toContain("Dashboard")
90+
expect(body).toContain("Mail")
91+
expect(body).toContain("Pricing")
92+
expect(body).toContain("Color Palette")
93+
expect(body).toContain("Mode")
94+
expect(body).toContain("Draft")
8895
expect(body).toContain('data-slot="tabs"')
89-
expect(body).toContain('data-slot="table"')
90-
expect(body).toContain("Feedback Gallery")
91-
expect(body).toContain("Content Gallery")
96+
expect(body).toContain("Cards Preview")
97+
expect(body).toContain("Revenue Pulse")
98+
expect(body).toContain("Surface Audit")
9299
expect(body).toContain("report-card")
93100
} finally {
94101
preview.kill("SIGTERM")
@@ -329,7 +336,7 @@ describe("agent-html CLI heavy gallery flows", () => {
329336
const response = await fetch(url)
330337
const body = await response.text()
331338

332-
expect(body).toContain("ahtml-gallery-hero-title")
339+
expect(body).toContain("ahtml-gallery-preset-select-row")
333340
expect(body).toContain(">team-ops</")
334341
expect(body).toContain('data-style-profile="team-ops"')
335342
expect(body).toContain('data-ahtml-treatment="review-card"')

packages/ahtml/src/cli/gallery-alignment.test.ts

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,42 @@ describe("gallery alignment", () => {
5151
expect(runtimeApp).toContain('value="preview"')
5252
expect(runtimeApp).toContain('value="components"')
5353
expect(runtimeApp).toContain("<Button")
54-
expect(runtimeApp).toContain("<Select")
54+
expect(runtimeApp).toContain("<Popover")
5555
expect(runtimeApp).toContain("<Accordion")
56-
expect(runtimeApp).toContain("Reset Draft")
57-
expect(runtimeApp).toContain("Save Current Style")
58-
expect(runtimeApp).toContain("Component gallery workbench")
59-
expect(runtimeApp).toContain('value="full"')
56+
expect(runtimeApp).toContain("Reset")
57+
expect(runtimeApp).toContain("Save Style")
58+
expect(runtimeApp).toContain('aria-label="Preview theme"')
59+
expect(runtimeApp).toContain("Preset chooser")
60+
expect(runtimeApp).toContain("<GalleryPreviewMeta")
61+
expect(runtimeApp).toContain("Gallery")
62+
expect(runtimeApp).toContain("Fullscreen")
63+
expect(runtimeApp).toContain('data-theme-mode={previewThemeMode}')
64+
expect(runtimeApp).toContain("GalleryExamplesPreviewContainer")
65+
expect(runtimeApp).toContain("More previews")
66+
expect(runtimeApp).toContain("Color Palette")
67+
expect(runtimeApp).toContain("Full component gallery")
68+
expect(runtimeApp).toContain("Inspector")
69+
expect(runtimeApp).toContain("Inspecting")
70+
expect(runtimeApp).toContain("DropdownMenu")
71+
expect(runtimeApp).toContain("<AccordionTrigger>Radius</AccordionTrigger>")
72+
expect(runtimeApp).toContain("<AccordionTrigger>Treatments</AccordionTrigger>")
73+
expect(runtimeApp).toContain("ahtml-gallery-token-row")
74+
expect(runtimeApp).toContain('<AccordionTrigger>{section.title}</AccordionTrigger>')
75+
expect(runtimeApp).toContain('title: "Primary"')
76+
expect(runtimeApp).toContain('title: "Border & Input"')
77+
expect(runtimeApp).toContain("ahtml-gallery-color-popover")
78+
expect(runtimeApp).toContain('value="dashboard"')
79+
expect(runtimeApp).toContain('value="mail"')
80+
expect(runtimeApp).toContain('value="colors"')
81+
expect(runtimeApp).toContain('setPreviewMode("selection")')
82+
expect(runtimeApp).toContain("Press Esc to release")
83+
expect(runtimeApp).toContain("ahtml-gallery-inspector-outline")
84+
expect(runtimeApp).toContain("Click to pin the current component")
85+
expect(runtimeApp).toContain('target.dataset.ahtmlPath')
86+
expect(runtimeApp).toContain('target.dataset.ahtmlRenderKind')
87+
expect(runtimeApp).toContain('target.dataset.ahtmlSource')
88+
expect(runtimeApp).toContain('label="Render"')
89+
expect(runtimeApp).toContain('label="Source"')
90+
expect(runtimeApp).toContain('label="Path"')
6091
})
6192
})

packages/ahtml/src/cli/index.mjs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
select,
66
spinner,
77
} from "@clack/prompts"
8-
import { StyleProfileSchema } from "@agent-html/core"
8+
import { normalizeStyleProfile, StyleProfileSchema } from "@agent-html/core"
99
import path from "node:path"
1010
import { fileURLToPath } from "node:url"
1111

@@ -544,7 +544,9 @@ function createGalleryRequestHandler() {
544544
) {
545545
try {
546546
const body = await readJsonBody(request)
547-
const profileInput = StyleProfileSchema.parse(body.styleProfile)
547+
const profileInput = StyleProfileSchema.parse(
548+
normalizeStyleProfile(body.styleProfile),
549+
)
548550
const saved = await saveUserStyleProfile(runtimePaths, profileInput, {
549551
overwrite: true,
550552
})

packages/ahtml/src/cli/runtime-renderability.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,16 @@ function createDocument(components: AgentDocument["components"]): AgentDocument
549549
typography: {
550550
fontSans: "",
551551
fontHeading: "",
552+
fontSerif: "",
553+
fontMono: "",
554+
letterSpacing: "",
555+
spacing: "",
556+
shadowColor: "",
557+
shadowOpacity: "",
558+
shadowBlur: "",
559+
shadowSpread: "",
560+
shadowOffsetX: "",
561+
shadowOffsetY: "",
552562
},
553563
cssVariableMap: {
554564
background: "",
@@ -566,12 +576,36 @@ function createDocument(components: AgentDocument["components"]): AgentDocument
566576
accent: "",
567577
accentForeground: "",
568578
destructive: "",
579+
destructiveForeground: "",
569580
border: "",
570581
input: "",
571582
ring: "",
583+
chart1: "",
584+
chart2: "",
585+
chart3: "",
586+
chart4: "",
587+
chart5: "",
588+
sidebar: "",
589+
sidebarForeground: "",
590+
sidebarPrimary: "",
591+
sidebarPrimaryForeground: "",
592+
sidebarAccent: "",
593+
sidebarAccentForeground: "",
594+
sidebarBorder: "",
595+
sidebarRing: "",
572596
radius: "",
573597
fontSans: "",
574598
fontHeading: "",
599+
fontSerif: "",
600+
fontMono: "",
601+
letterSpacing: "",
602+
spacing: "",
603+
shadowColor: "",
604+
shadowOpacity: "",
605+
shadowBlur: "",
606+
shadowSpread: "",
607+
shadowOffsetX: "",
608+
shadowOffsetY: "",
575609
},
576610
},
577611
componentStyle: {
@@ -600,9 +634,23 @@ function emptyColorTokenSet() {
600634
accent: "",
601635
accentForeground: "",
602636
destructive: "",
637+
destructiveForeground: "",
603638
border: "",
604639
input: "",
605640
ring: "",
641+
chart1: "",
642+
chart2: "",
643+
chart3: "",
644+
chart4: "",
645+
chart5: "",
646+
sidebar: "",
647+
sidebarForeground: "",
648+
sidebarPrimary: "",
649+
sidebarPrimaryForeground: "",
650+
sidebarAccent: "",
651+
sidebarAccentForeground: "",
652+
sidebarBorder: "",
653+
sidebarRing: "",
606654
}
607655
}
608656

0 commit comments

Comments
 (0)