Form Layout Guide
Form Layout Configuration
Section titled “Form Layout Configuration”@enlolab/forms provides a semantic, UX-first layout system that allows you to create responsive form layouts without thinking about technical details like grid columns or breakpoints. The system adapts automatically to any container width, making it perfect for forms that live in sidebars, modals, or full-width pages.
Layout Modes
Section titled “Layout Modes”The layout system offers two modes:
1. Simple Mode (auto) - Recommended
Section titled “1. Simple Mode (auto) - Recommended”The Simple mode is perfect for 90% of use cases. It automatically adapts to the container width using CSS Grid’s auto-fit feature. You only need to think in terms of:
- Density: How spaced out should fields be?
- Field width: Should this field be full width, half, or third?
layout: { mode: "auto", auto: { density: "normal", // "relaxed" | "normal" | "compact" minFieldWidth: 240, // Optional: minimum field width in pixels maxColumns: 3, // Optional: maximum number of columns }}How it works:
- The form automatically calculates how many columns fit based on the container width
- Fields with
width: "full"always take the full width - Other fields automatically arrange themselves side by side when there’s space
- Works perfectly in containers of any width (30%, 50%, 100%, etc.)
2. Advanced Mode (grid)
Section titled “2. Advanced Mode (grid)”The Advanced mode gives you full control over columns and breakpoints. Use this when you need precise control over the layout.
layout: { mode: "grid", grid: { columns: { mobile: 1, // 1 column on mobile tablet: 2, // 2 columns on tablet desktop: 4, // 4 columns on desktop }, gap: { mobile: "sm", // Small gap on mobile desktop: "md", // Medium gap on desktop }, }}Density
Section titled “Density”Density controls the spacing between fields and affects the overall feel of the form:
relaxed: More space between fields (gap-6) - better for forms with few fieldsnormal: Standard spacing (gap-4) - good for most formscompact: Tighter spacing (gap-2) - good for dense forms with many fields
layout: { mode: "auto", auto: { density: "relaxed", // or "normal" | "compact" }}Field Width (Semantic)
Section titled “Field Width (Semantic)”Instead of thinking about colSpan numbers, you think in semantic terms:
"auto": Let the system decide (default)"full": Field takes full width (good for textareas, date ranges, etc.)"half": Field takes half width (good for pairs like first/last name)"third": Field takes one third width (good for groups of three)
fields: { fullName: { type: "text", label: "Full Name", layout: { width: { mobile: "full", // Full width on mobile desktop: "half", // Half width on desktop } } }, bio: { type: "textarea", label: "Biography", layout: { width: { mobile: "full", desktop: "full", // Always full width } } }}Breakpoints (Semantic)
Section titled “Breakpoints (Semantic)”The system uses semantic breakpoints instead of technical Tailwind breakpoints:
mobile: Mobile devices (default, no prefix)tablet: Tablets (maps tomd:in Tailwind)desktop: Desktop (maps tolg:in Tailwind)
This makes it easier to think about “mobile vs desktop” rather than “sm vs lg”.
Complete Examples
Section titled “Complete Examples”Simple Form (Auto Mode)
Section titled “Simple Form (Auto Mode)”const contactForm = FormFactory({ formId: "contact-form", layout: { mode: "auto", auto: { density: "normal", minFieldWidth: 260, maxColumns: 3, }, }, fields: { firstName: { type: "text", label: "First Name", layout: { width: { mobile: "full", desktop: "half", }, }, schema: z.string().min(1), }, lastName: { type: "text", label: "Last Name", layout: { width: { mobile: "full", desktop: "half", }, }, schema: z.string().min(1), }, email: { type: "email", label: "Email", layout: { width: { mobile: "full", desktop: "full", }, }, schema: z.string().email(), }, message: { type: "textarea", label: "Message", layout: { width: { mobile: "full", desktop: "full", }, }, schema: z.string().min(10), }, },});Advanced Form (Grid Mode)
Section titled “Advanced Form (Grid Mode)”const advancedForm = FormFactory({ formId: "advanced-form", layout: { mode: "grid", grid: { columns: { mobile: 1, tablet: 2, desktop: 4, }, gap: { mobile: "sm", tablet: "md", desktop: "lg", }, }, }, fields: { header: { type: "html", html: "<h2>Form Header</h2>", layout: { width: { desktop: "full", // Spans all 4 columns }, }, }, field1: { type: "text", label: "Field 1", layout: { width: { desktop: "half", // Spans 2 of 4 columns }, }, schema: z.string(), }, field2: { type: "text", label: "Field 2", layout: { width: { desktop: "half", // Spans 2 of 4 columns }, }, schema: z.string(), }, },});Field Visibility
Section titled “Field Visibility”You can control field visibility per breakpoint:
fields: { mobileOnlyField: { type: "text", label: "Mobile Only", layout: { visibility: { desktop: "hidden", // Hidden on desktop } }, schema: z.string(), }, desktopOnlyField: { type: "text", label: "Desktop Only", layout: { visibility: { mobile: "hidden", // Hidden on mobile } }, schema: z.string(), },}Field Order
Section titled “Field Order”Control the visual order of fields:
fields: { firstField: { type: "text", label: "First", layout: { order: 1, }, schema: z.string(), }, secondField: { type: "text", label: "Second", layout: { order: 2, }, schema: z.string(), },}Best Practices
Section titled “Best Practices”- Use Simple Mode by Default: Start with
mode: "auto"- it handles 90% of cases perfectly - Think Semantically: Use
"full","half","third"instead of column numbers - Mobile First: Always specify mobile width, desktop is optional
- Density Matters: Choose density based on form complexity
- Full Width for Long Fields: Use
width: "full"for textareas, date ranges, sliders - Test in Different Containers: The auto mode adapts to any container width
When to Use Each Mode
Section titled “When to Use Each Mode”Use Simple Mode (auto) when:
Section titled “Use Simple Mode (auto) when:”- ✅ You want the form to adapt to any container width
- ✅ You don’t need precise control over columns
- ✅ You’re building a standard form (contact, registration, etc.)
- ✅ You want the simplest possible configuration
Use Advanced Mode (grid) when:
Section titled “Use Advanced Mode (grid) when:”- ✅ You need exact control over columns per breakpoint
- ✅ You’re building a complex dashboard or admin form
- ✅ You need custom breakpoint mappings
- ✅ You’re a developer who wants full control
Container Width Adaptation
Section titled “Container Width Adaptation”One of the key benefits of Simple mode is automatic adaptation:
- 30% width container: Form will typically show 1 column
- 50% width container: Form will show 1-2 columns
- 100% width container: Form will show 2-3 columns (based on
maxColumns)
The system uses minFieldWidth to determine how many columns fit, so it works perfectly in any context.