UNPKG

@upstart.gg/sdk

Version:

You can test the CLI without recompiling by running:

549 lines (541 loc) 15.1 kB
import { defineBrickManifest } from "../../brick-manifest.js"; import { cssLength } from "../props/css-length.js"; import { alignItems, justifyContent } from "../props/align.js"; import { defineProps } from "../props/helpers.js"; import { shadow } from "../props/effects.js"; import { colorPreset } from "../props/color-preset.js"; import { loop } from "../props/dynamic.js"; import { border, rounding } from "../props/border.js"; import { direction } from "../props/direction.js"; import { Type } from "@sinclair/typebox"; import { RxBox } from "react-icons/rx"; //#region src/shared/bricks/manifests/box.manifest.ts const manifest = defineBrickManifest({ type: "box", category: "container", name: "Box", description: "A container for stacking bricks horizontally or vertically.", aiInstructions: `Use the box component as a flexible container for organizing and arranging multiple bricks in horizontal or vertical layouts. WHEN TO USE: - Grouping related content elements (text + image + button) - Creating card-like layouts with multiple components - Building responsive grid systems with wrapping - Organizing form elements or input groups - Displaying repeated data from queries (products, team members, blog posts) - Creating structured layouts with consistent spacing LAYOUT GUIDELINES: - direction: "flex-col" for vertical stacking, "flex-row" for horizontal arrangement - gap: "0.5rem" for tight spacing, "1rem" for standard, "2rem" for spacious layouts - padding: "1rem" for standard padding, "2rem" for generous spacing, "0" for edge-to-edge - wrap: true for responsive grids that wrap on smaller screens, false for fixed layouts - justifyContent: "justify-start" for left-align, "justify-center" for center, "justify-between" for space-between - alignItems: "items-stretch" for equal heights, "items-center" for center-align, "items-start" for top-align STYLING OPTIONS: - colorPreset: Use light backgrounds like "primary-50", "neutral-100", "secondary-100" for content containers - rounding: "rounded-md" for standard, "rounded-lg" for friendly, "rounded-xl"/"rounded-2xl" for modern - border: Add subtle borders with "border" width and colors like "border-gray-200", "border-primary-300" - shadow: "shadow-sm" for subtle depth, "shadow-md" for cards, "shadow-lg" for prominence CONTENT RULES: - Must contain at least 2 child bricks to be useful - Cannot contain other box components as direct children - Commonly contains: text, image, button, icon combinations - Perfect for repeating patterns using loop data DYNAMIC CONTENT: - Use loop property to repeat the box itself over data queries - Template variables work in all child components: "{{ product.name}}", "{{user.email}}" - Great for: product catalogs, team directories, blog listings AVOID: - Single child elements (use individual brick instead) - Nesting boxes inside boxes (use single box with proper layout) - Complex nested structures (break into separate boxes)`, isContainer: true, defaultWidth: { desktop: "auto", mobile: "100%" }, defaultHeight: { desktop: "auto" }, icon: RxBox, props: defineProps({ colorPreset: Type.Optional(colorPreset({ title: "Color" })), direction: direction({ default: "flex-col", title: "Direction", description: "Direction of the box layout" }), justifyContent: Type.Optional(justifyContent({ default: "justify-center" })), alignItems: Type.Optional(alignItems({ default: "items-stretch" })), gap: Type.Optional(cssLength({ title: "Gap", default: "1rem", description: "Gap between children bricks.", "ai:instructions": "Can be a tailwind gap class like 'gap-1' or 'gap-2', or a custom value like '10px'", "ui:placeholder": "Not specified", "ui:styleId": "styles:gap" })), padding: Type.Optional(cssLength({ default: "1rem", description: "Padding inside the box.", "ai:instructions": "Use only a single value like '1rem' or '10px'", title: "Padding", "ui:placeholder": "Not specified", "ui:styleId": "styles:padding" })), wrap: Type.Optional(Type.Boolean({ title: "Wrap", description: "Wrap bricks if they overflow the section.", default: false, "ui:styleId": "styles:wrap" })), rounding: rounding({ default: "rounded-md" }), border: Type.Optional(border()), shadow: Type.Optional(shadow()), loop: Type.Optional(loop()), $children: Type.Array(Type.Any(), { "ui:field": "hidden", description: "List of nested bricks", default: [], examples: [[{ type: "text", props: { content: "Hello World" } }, { type: "image", props: { src: "https://via.placeholder.com/150", alt: "Placeholder Image" } }]] }) }) }); const examples = [ { description: "Simple vertical layout - Basic text and image combination", type: "box", props: { direction: "flex-col", gap: "1rem", padding: "1.5rem", $children: [ { type: "text", props: { content: "<h3>Welcome to Our Service</h3><p>We provide innovative solutions for modern businesses.</p>" } }, { type: "image", props: { src: "https://via.placeholder.com/300x200", alt: "Service showcase" } }, { type: "button", props: { label: "Learn More", link: "/services" } } ] } }, { description: "Horizontal layout with wrapping - Perfect for responsive image galleries", type: "box", props: { direction: "flex-row", gap: "1rem", wrap: true, justifyContent: "justify-center", padding: "1rem", $children: [ { type: "image", props: { src: "https://via.placeholder.com/150", alt: "Gallery image 1" } }, { type: "image", props: { src: "https://via.placeholder.com/150", alt: "Gallery image 2" } }, { type: "image", props: { src: "https://via.placeholder.com/150", alt: "Gallery image 3" } }, { type: "image", props: { src: "https://via.placeholder.com/150", alt: "Gallery image 4" } } ] } }, { description: "Content card with background and border - Professional presentation style", type: "box", props: { direction: "flex-col", gap: "1rem", padding: "2rem", colorPreset: { color: "primary-50" }, border: { width: "border", color: "border-primary-200" }, rounding: "rounded-lg", shadow: "shadow-md", $children: [ { type: "text", props: { content: "<h3>Featured Article</h3><p>Discover the latest trends in technology and innovation that are shaping our future.</p>" } }, { type: "image", props: { src: "https://via.placeholder.com/400x250", alt: "Technology trends" } }, { type: "button", props: { label: "Read Full Article", link: "/articles/tech-trends" } } ] } }, { description: "Employee directory using dynamic data - Shows team member profiles", type: "box", props: { direction: "flex-col", gap: "1.5rem", padding: "2rem", colorPreset: { color: "neutral-100" }, rounding: "rounded-lg", border: { width: "border", color: "border-neutral-300" }, loop: { over: "allEmployees" }, $children: [ { type: "image", props: { src: "{{allEmployees.photo}}", alt: "Photo of {{allEmployees.name}}" } }, { type: "text", props: { content: "<h3>{{allEmployees.name}}</h3><p><strong>{{allEmployees.position}}</strong></p><p>{{allEmployees.department}}{{allEmployees.email}}</p>" } }, { type: "button", props: { label: "Contact {{allEmployees.name}}", link: "mailto:{{allEmployees.email}}" } } ] } }, { description: "Blog post cards with horizontal layout - Great for article previews", type: "box", props: { direction: "flex-row", gap: "2rem", padding: "1.5rem", justifyContent: "justify-start", alignItems: "items-stretch", colorPreset: { color: "secondary-50" }, rounding: "rounded-lg", shadow: "shadow-sm", loop: { over: "blogPosts" }, $children: [ { type: "image", props: { src: "{{blogPosts.featuredImage}}", alt: "{{blogPosts.title}}" } }, { type: "text", props: { content: "<h4>{{blogPosts.title}}</h4><p>{{blogPosts.excerpt}}</p><p><em>By {{blogPosts.author}}{{blogPosts.publishDate}}</em></p>" } }, { type: "button", props: { label: "Read More", link: "/blog/{{blogPosts.slug}}" } } ] } }, { description: "Product showcase cards with pricing - Perfect for e-commerce displays", type: "box", props: { direction: "flex-col", gap: "1rem", padding: "1.5rem", justifyContent: "justify-center", alignItems: "items-center", colorPreset: { color: "accent-50" }, border: { width: "border-2", color: "border-accent-200" }, rounding: "rounded-xl", shadow: "shadow-md", loop: { over: "featuredProducts" }, $children: [ { type: "image", props: { src: "{{featuredProducts.image}}", alt: "{{featuredProducts.name}}" } }, { type: "text", props: { content: "<h3>{{featuredProducts.name}}</h3><p>{{featuredProducts.description}}</p><p><strong>${{featuredProducts.price}}</strong></p>" } }, { type: "button", props: { label: "Add to Cart", link: "/cart/add/{{featuredProducts.id}}" } } ] } }, { description: "Team members with wrapping - Responsive grid that adapts to screen size", type: "box", props: { direction: "flex-row", gap: "2rem", padding: "2rem", wrap: true, justifyContent: "justify-center", alignItems: "items-start", colorPreset: { color: "secondary-100" }, rounding: "rounded-lg", loop: { over: "teamMembers" }, $children: [ { type: "image", props: { src: "{{teamMembers.avatar}}", alt: "{{teamMembers.fullName}}" } }, { type: "text", props: { content: "<h4>{{teamMembers.fullName}}</h4><p><strong>{{teamMembers.role}}</strong></p><p>{{teamMembers.bio}}</p>" } }, { type: "button", props: { label: "View Profile", link: "/team/{{teamMembers.slug}}" } } ] } }, { description: "Event listings with accent styling - Prominent call-to-action design", type: "box", props: { direction: "flex-col", gap: "1.25rem", padding: "2.5rem", alignItems: "items-center", colorPreset: { color: "accent-100" }, border: { width: "border-2", color: "border-accent-300" }, rounding: "rounded-lg", shadow: "shadow-lg", loop: { over: "upcomingEvents" }, $children: [ { type: "icon", props: { icon: "mdi:calendar-event", size: "2rem", color: "#f59e0b" } }, { type: "text", props: { content: "<h3>{{upcomingEvents.title}}</h3><p><strong>{{upcomingEvents.date}} at {{upcomingEvents.time}}</strong></p><p>{{upcomingEvents.venue}}{{upcomingEvents.city}}</p><p>{{upcomingEvents.description}}</p>" } }, { type: "button", props: { label: "Register Now", link: "/events/{{upcomingEvents.slug}}/register" } } ] } }, { description: "Customer testimonials with star ratings - Social proof presentation", type: "box", props: { direction: "flex-col", gap: "1rem", padding: "3rem", justifyContent: "justify-center", alignItems: "items-center", colorPreset: { color: "neutral-50" }, shadow: "shadow-lg", rounding: "rounded-2xl", loop: { over: "customerTestimonials" }, $children: [ { type: "icon", props: { icon: "mdi:format-quote-open", size: "2rem", color: "#6b7280" } }, { type: "text", props: { content: "<p style=\"text-align: center\"><em>\"{{customerTestimonials.quote}}\"</em></p><p style=\"text-align: center\"><strong>{{customerTestimonials.customerName}}</strong></p><p style=\"text-align: center\">{{customerTestimonials.company}}{{customerTestimonials.position}}</p>" } }, { type: "icon", props: { icon: "mdi:star", size: "1.5rem", color: "#fbbf24" } } ] } }, { description: "Portfolio project showcase - Creative work presentation with client details", type: "box", props: { direction: "flex-row", gap: "1.5rem", padding: "2rem", alignItems: "items-start", justifyContent: "justify-start", colorPreset: { color: "primary-50" }, border: { width: "border", color: "border-primary-200" }, rounding: "rounded-lg", loop: { over: "portfolioProjects" }, $children: [ { type: "image", props: { src: "{{portfolioProjects.thumbnail}}", alt: "{{portfolioProjects.projectName}}" } }, { type: "text", props: { content: "<h4>{{portfolioProjects.projectName}}</h4><p><strong>{{portfolioProjects.client}}</strong></p><p>{{portfolioProjects.category}}{{portfolioProjects.year}}</p><p>{{portfolioProjects.shortDescription}}</p>" } }, { type: "button", props: { label: "View Project", link: "/portfolio/{{portfolioProjects.slug}}" } } ] } }, { description: "News article previews with categories - Clean editorial layout", type: "box", props: { direction: "flex-col", gap: "1.5rem", padding: "2rem", colorPreset: { color: "neutral-100" }, border: { width: "border", color: "border-neutral-300" }, rounding: "rounded-md", loop: { over: "latestNews" }, $children: [{ type: "text", props: { content: "<h3>{{latestNews.headline}}</h3><p><strong>{{latestNews.category}}</strong> • {{latestNews.publishedDate}}</p><p>{{latestNews.summary}}</p>" } }, { type: "button", props: { label: "Read Full Article", link: "/news/{{latestNews.slug}}" } }] } }, { description: "Service packages with icons and pricing - Professional service presentation", type: "box", props: { direction: "flex-col", gap: "1rem", padding: "2rem", justifyContent: "justify-center", alignItems: "items-center", colorPreset: { color: "secondary-200" }, rounding: "rounded-xl", shadow: "shadow-md", loop: { over: "companyServices" }, $children: [ { type: "icon", props: { icon: "{{companyServices.iconName}}", size: "2.5rem", color: "{{companyServices.iconColor}}" } }, { type: "text", props: { content: "<h4 style='text-align: center'>{{companyServices.serviceName}}</h4><p style='text-align: center'>{{companyServices.description}}</p><p style='text-align: center'><strong>Starting at ${{companyServices.price}}</strong></p>" } }, { type: "button", props: { label: "Learn More", link: "/services/{{companyServices.serviceSlug}}" } } ] } } ]; //#endregion export { examples, manifest }; //# sourceMappingURL=box.manifest.js.map