Chris Tate 5 сар өмнө
parent
commit
f34e6ad3e6

+ 2 - 2
apps/web/app/api/generate/route.ts

@@ -8,7 +8,7 @@ const SYSTEM_PROMPT = `You are a UI generator that outputs JSONL (JSON Lines) pa
 AVAILABLE COMPONENTS (20):
 
 Layout:
-- Card: { title?: string, description?: string } - Container card. Has children.
+- Card: { title?: string, description?: string, maxWidth?: "sm"|"md"|"lg"|"full", centered?: boolean } - Container card. Has children. Use maxWidth:"sm" + centered:true for login/signup forms.
 - Stack: { direction?: "horizontal"|"vertical", gap?: "sm"|"md"|"lg" } - Flex container. Has children.
 - Grid: { columns?: 2|3|4, gap?: "sm"|"md"|"lg" } - Grid layout. Has children.
 - Divider: {} - Horizontal separator line
@@ -50,7 +50,7 @@ RULES:
 
 EXAMPLE:
 {"op":"set","path":"/root","value":"card"}
-{"op":"add","path":"/elements/card","value":{"key":"card","type":"Card","props":{"title":"Contact"},"children":["name","submit"]}}
+{"op":"add","path":"/elements/card","value":{"key":"card","type":"Card","props":{"title":"Contact","maxWidth":"sm","centered":true},"children":["name","submit"]}}
 {"op":"add","path":"/elements/name","value":{"key":"name","type":"Input","props":{"label":"Name","name":"name"}}}
 {"op":"add","path":"/elements/submit","value":{"key":"submit","type":"Button","props":{"label":"Submit","variant":"primary"}}}
 

+ 8 - 6
apps/web/components/demo.tsx

@@ -263,8 +263,10 @@ export function Demo() {
     switch (type) {
       // Layout
       case "Card":
+        const maxWidthClass = props.maxWidth === "sm" ? "max-w-xs min-w-[280px]" : props.maxWidth === "md" ? "max-w-sm min-w-[320px]" : props.maxWidth === "lg" ? "max-w-md min-w-[360px]" : "";
+        const centeredClass = props.centered ? "mx-auto" : "";
         return (
-          <div key={element.key} className={`border border-border rounded-lg p-3 bg-background ${baseClass}`}>
+          <div key={element.key} className={`border border-border rounded-lg p-3 bg-background ${maxWidthClass} ${centeredClass} ${baseClass}`}>
             {props.title && <div className="font-semibold text-sm mb-1 text-left">{props.title as string}</div>}
             {props.description && <div className="text-[10px] text-muted-foreground mb-2 text-left">{props.description as string}</div>}
             <div className="space-y-2">{renderChildren()}</div>
@@ -323,7 +325,7 @@ export function Demo() {
               <span className={selectedValue ? "text-foreground" : "text-muted-foreground/50"}>
                 {selectedValue || props.placeholder as string || "Select..."}
               </span>
-              <span className={`transition-transform ${isOpen ? "rotate-180" : ""}`}>v</span>
+              <svg className={`w-3 h-3 transition-transform ${isOpen ? "rotate-180" : ""}`} fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" /></svg>
             </div>
             {isOpen && selectOptions.length > 0 && (
               <div className="absolute z-10 top-full left-0 right-0 mt-1 bg-card border border-border rounded shadow-lg overflow-hidden">
@@ -334,7 +336,7 @@ export function Demo() {
                       setSelectValues((prev) => ({ ...prev, [element.key]: opt }));
                       setOpenSelect(null);
                     }}
-                    className={`px-2 py-1.5 text-xs cursor-pointer hover:bg-muted transition-colors ${selectedValue === opt ? "bg-muted" : ""}`}
+                    className={`px-2 py-1.5 text-xs text-left cursor-pointer hover:bg-muted transition-colors ${selectedValue === opt ? "bg-muted" : ""}`}
                   >
                     {opt}
                   </div>
@@ -478,10 +480,10 @@ export function Demo() {
     if (!root) return null;
 
     return (
-      <div className="animate-in fade-in duration-200 w-full">
+      <div className="animate-in fade-in duration-200 w-full min-h-full flex flex-col items-center">
         {renderElement(root, currentTree.elements)}
         {actionFired && (
-          <div className="mt-3 text-xs font-mono text-muted-foreground animate-in fade-in slide-in-from-bottom-2">
+          <div className="mt-3 text-xs font-mono text-muted-foreground text-center animate-in fade-in slide-in-from-bottom-2">
             onAction()
           </div>
         )}
@@ -623,7 +625,7 @@ export function Demo() {
         {/* Rendered output */}
         <div>
           <div className="text-xs text-muted-foreground mb-2 font-mono">render</div>
-          <div className="border border-border rounded p-3 bg-card h-96 overflow-auto">
+          <div className="border border-border rounded p-3 bg-card h-96 overflow-auto flex flex-col">
             {renderPreview()}
           </div>
         </div>