Skip to content

Form Layouts

Organize your workflow forms into sections with custom grid layouts. This feature is completely optional - workflows without layouts will display fields in a simple list for backwards compatibility.

form:
layout:
sections:
- id: "section_id"
title: "Section Title"
description: "Optional description"
initial: true # Show this section during initial submission
grid:
- ["field1", "field2"] # Row with 2 fields
- ["field3"] # Row with 1 field (full width)
- ["field4", "field5", "field6"] # Row with 3 fields
# Optional: limit which sections appear in the PDF export
completed_sections:
- invoice_header_info
- line_items_section
- totals_section
# Optional responsive settings
responsive:
tablet: 2 # Max columns on tablet
mobile: 1 # Max columns on mobile

Controls which sections are rendered in the PDF export. When set, only the listed section IDs appear in the printed document — all others are omitted. The order of the list determines the print order.

Use this when your form has sections that are only relevant on-screen (e.g. progress indicators, help text panels) and should not clutter the printed output.

form:
layout:
completed_sections:
- invoice_header_info
- line_items_section
- totals_section
sections:
- id: invoice_header_info
title: "Invoice Details"
grid: [["vendor", "invoice_date", "invoice_number"]]
- id: line_items_section
title: "Line Items"
grid: [["items"]]
- id: totals_section
title: "Totals"
grid: [["subtotal", "tax", "total"]]
- id: internal_notes
title: "Internal Notes" # ← excluded from PDF
grid: [["notes"]]

If completed_sections is omitted, all sections are printed.

The validator checks that every ID listed in completed_sections exists in sections.

Unique identifier for the section. Used to reference sections in workflow steps.

Display title shown in the section header with a gradient background.

Optional description displayed below the title to provide context.

Set to true to show this section when the requestor creates the workflow. Only fields in initial: true sections are displayed and required to be filled during submission.

Per-field layout overrides for this section. Keys are field names; values set layout attributes that apply only when that field appears in this section. Overrides layout.fields for the same field.

sections:
- id: summary
grid: [["amount", "tax"]]
fields:
amount:
align: right
bottom_border: true # only in this section
tax:
align: right

Array of arrays defining field layout. Each inner array represents a row, and field names in the array are displayed side-by-side.

Example:

grid:
- ["name", "email"] # Two fields side-by-side
- ["phone"] # Single field, full width
- ["city", "state", "zip"] # Three fields in one row

Layout attributes control how a field looks in a section — alignment, borders, label placement. They are intentionally separate from field identity (type, label, required, etc.) so the same field can appear differently in different sections without duplication.

Field identity — defined on form.fields, survives layout changes:

AttributeDescription
type, label, requiredCore identity
options, validation, placeholderInput behaviour
width, alignException: valid on item_fields inside line_items (table column properties)

Layout attributes — defined in layout.fields or section.fields:

AttributeValuesDescription
alignleft | center | rightValue alignment in read-only display
bottom_bordertrue | falseFull-width separator below the field
spanfull | half | autoGrid column span hint
valigntop | middle | bottomVertical alignment
label_positionabove | inline | hiddenLabel placement

Form-scope layout attributes applied to a field across all sections. Override per-section using section.fields.

form:
layout:
fields:
amount:
align: right # right-aligned in every section by default
notes:
label_position: above
section.fields → layout.fields → field-level attribute (legacy fallback)
form:
fields:
- name: amount
type: currency
label: Amount
required: true # identity only — no layout here
layout:
fields:
amount:
align: right # right-aligned everywhere unless overridden
sections:
- id: request_summary
title: "Summary"
grid:
- ["label_text", "amount"]
fields:
amount:
align: right
bottom_border: true # separator only in this section
- id: data_entry
title: "Request Details"
grid:
- ["amount"]
fields:
amount:
align: left # override: left-aligned in this section
bottom_border: false

Control how layouts adapt to different screen sizes:

responsive:
tablet: 2 # Maximum 2 columns per row on tablets (641px - 1024px)
mobile: 1 # Maximum 1 column per row on mobile (<= 640px)

When responsive settings are applied:

  • Desktop: Uses the actual number of fields in each row (up to 6)
  • Tablet: Limits columns to the tablet value
  • Mobile: Limits columns to the mobile value (typically 1 for vertical stacking)

Control which sections are visible and editable at each approval step using view_sections and edit_sections:

workflow:
manager_approval:
name: "Manager Approval"
type: "decision"
approver: "manager"
view_sections: ["employee_info"] # Read-only sections (grayed out)
edit_sections: ["approval_info"] # Editable sections
on_approve:
continue_to: "hr_final"
hr_final:
name: "HR Final Approval"
type: "decision"
approver: "hr_manager"
view_sections: ["employee_info", "approval_info"] # Can view previous sections
edit_sections: ["hr_notes"] # Can edit HR notes section
on_approve:
end_workflow: true

If view_sections and edit_sections are not specified in a workflow step:

  • All sections are displayed in view mode (read-only)

This ensures safe defaults - approvers can see all information but cannot accidentally modify fields unless explicitly allowed.

name: "Employee Onboarding"
description: "Multi-step onboarding process"
form:
layout:
sections:
- id: "personal_info"
title: "Employee Details"
description: "To be filled out by the new employee"
initial: true # Shown during workflow creation
grid:
- ["full_name", "personal_email"] # 2 columns
- ["phone_number"] # Full width
- ["start_date", "position"] # 2 columns
- id: "it_setup"
title: "IT Equipment Setup"
description: "IT department will configure equipment"
grid:
- ["laptop_choice"] # Full width
- ["monitor_request", "keyboard_request", "mouse_request"] # 3 columns
- ["additional_software"] # Full width
- id: "hr_verification"
title: "HR Verification"
description: "HR final verification and employee ID assignment"
grid:
- ["employee_id", "company_email"] # 2 columns
- ["hr_notes"] # Full width
responsive:
tablet: 2 # Max 2 columns on tablet
mobile: 1 # Stack vertically on mobile
fields:
# Personal Info Fields
- name: "full_name"
type: "text"
label: "Full Name"
required: true
- name: "personal_email"
type: "email"
label: "Personal Email"
required: true
- name: "phone_number"
type: "text"
label: "Phone Number"
- name: "start_date"
type: "date"
label: "Start Date"
required: true
- name: "position"
type: "text"
label: "Position / Title"
required: true
# IT Setup Fields
- name: "laptop_choice"
type: "radio"
label: "Laptop Choice"
display_as: "buttons"
options:
- { value: "macbook_pro", label: "MacBook Pro" }
- { value: "dell_xps", label: "Dell XPS" }
- { value: "lenovo_thinkpad", label: "Lenovo ThinkPad" }
- name: "monitor_request"
type: "checkbox"
label: "External Monitor"
- name: "keyboard_request"
type: "checkbox"
label: "External Keyboard"
- name: "mouse_request"
type: "checkbox"
label: "External Mouse"
- name: "additional_software"
type: "textarea"
label: "Additional Software Requirements"
# HR Verification Fields
- name: "employee_id"
type: "text"
label: "Employee ID"
required: true
- name: "company_email"
type: "email"
label: "Company Email Address"
required: true
- name: "hr_notes"
type: "textarea"
label: "HR Notes"
workflow:
it_provisioning:
name: "IT Provisioning"
type: "decision"
approver: "it_support"
view_sections: ["personal_info"] # Can view employee details
edit_sections: ["it_setup"] # Can edit IT equipment setup
on_complete:
continue_to: "hr_finalization"
hr_finalization:
name: "HR Finalization"
type: "decision"
approver: "hr_manager"
view_sections: ["personal_info", "it_setup"] # Can view both previous sections
edit_sections: ["hr_verification"] # Can edit HR verification
on_approve:
end_workflow: true

Column-Based Layouts (Alternative to Grid)

Section titled “Column-Based Layouts (Alternative to Grid)”

Instead of row-based grids, you can use column-based layouts for vertical field stacking:

form:
layout:
sections:
- id: invoice_header
title: "Invoice Information"
columns:
- [customer_name, customer_address, customer_phone] # Column 1
- [invoice_no, invoice_date, due_date] # Column 2
column_widths: ["2", "1"] # First column 2x wider than second

Control relative column widths with column_widths:

column_widths: ["2", "1"] # 2:1 ratio (first column is twice as wide)
column_widths: ["1", "1", "1"] # Equal width columns
column_widths: ["auto", "1fr"] # First column auto-sizes, second fills remaining space

Width Values:

  • Numbers ("1", "2", "3") - Relative proportions
  • "auto" - Content-based width (useful for images/logos)
  • "1fr" - Fills available space

Common Uses:

  • Logo + text columns: ["auto", "1fr"]
  • Narrow + wide columns: ["1", "2"]
  • Equal columns: ["1", "1"]

Add branded headers and informational footers to your forms:

form:
header:
grid:
- [company_logo, company_name, company_address]
fields:
- name: company_logo
type: image
source: "company"
height: 64px
show_label: false
form:
header:
columns:
- [company_logo] # Column 1: Logo
- [company_name, company_address, company_npwp] # Column 2: Text info
column_widths: ["auto", "1fr"] # Logo auto-sizes, text fills remaining
form:
footer:
grid:
- [footer_note]
- [approval_date, approved_by, authorized_signature]

Alternative footer format with explicit item control:

footer:
columns:
desktop: 3
tablet: 2
mobile: 1
padding: "16px"
background: "#f8f9fa"
items:
- type: message
content: "Document ID: GBB-FO-001 Ver 1.0/03-06-2024"
align: right
- type: field
field_name: approval_date

Header/Footer Use Cases:

  • Company branding (logos, addresses)
  • Document metadata (version numbers, dates)
  • Legal disclaimers and notes
  • Signature fields and approval dates
  • Reference numbers and barcodes

Fine-Grained Section Control (Mixed Sections)

Section titled “Fine-Grained Section Control (Mixed Sections)”

For advanced scenarios where some fields in a section should be editable while others are read-only:

workflow:
finance_approval:
mixed_sections:
totals_section:
editable: ["authorized_signature", "approval_notes"]
# All other fields in totals_section are read-only

This allows precise control over field editability within a single section.


When rendered, sections will appear with:

  1. Section Header - Gradient blue background with:

    • Section title (large, bold)
    • Section description (smaller, gray)
    • “Read-only” badge for view-only sections
  2. Section Content - White background with:

    • Grid-based field layout
    • Responsive column adjustments
    • Proper field spacing
  3. Field States:

    • Editable: Normal input fields with focus states
    • Read-only: Grayed out with pointer-events disabled

Workflows without the layout section will:

  • Display all fields in a simple vertical list
  • Work exactly as before
  • Require no changes to existing YAML files
  1. Initial Section: Always mark at least one section with initial: true for workflow creation forms

  2. Logical Grouping: Group related fields into sections (e.g., “Personal Info”, “Financial Details”, “Approval Info”)

  3. Responsive Design: Use responsive settings to ensure forms work well on mobile devices

  4. Section Visibility: Use view_sections and edit_sections to:

    • Show previous information to approvers (view)
    • Allow approvers to fill in their specific sections (edit)
    • Maintain data integrity by limiting edit access
  5. Grid Layout:

    • Use 2-3 columns for most forms
    • Use full-width (1 column) for text areas and long text fields
    • Use 3+ columns sparingly (only for very short fields like checkboxes)
  6. Field Names: Ensure all field names in grid arrays exist in the fields list

  7. Layout Attributes: Keep align, bottom_border, and other visual attributes in layout.fields or section.fields, not on form.fields. Exception: align and width on item_fields inside line_items stay on the field (they define table column properties).

The parser automatically validates:

  • Section IDs are unique
  • All field names in grids exist in the fields list
  • All section references in workflow steps exist in the layout
  • Grid structure is valid (arrays of arrays)
  • layout.fields and section.fields keys match valid field names
  • Layout attribute values are within allowed sets (align must be left/center/right, etc.)

Invalid configurations will be caught when uploading the YAML file.