Files
trackgo-fe/.agents/skills/form-layout/SKILL.md
T
shancheas ff6814d038 feat: add new skills for coding standards, continuous learning, detail layout, form layout, project guidelines, security review, and verification loop
- Introduced coding standards for TypeScript and React in SKILL.md.
- Added continuous learning skill with configuration and evaluation scripts.
- Created detail layout guidelines for read-only pages.
- Established form layout rules for data-entry forms.
- Documented project guidelines for the frontend monorepo.
- Implemented security review checklist for frontend/Electron applications.
- Developed a verification loop skill for comprehensive session checks.

This commit enhances the skill set available for developers, ensuring adherence to best practices and improving code quality.
2026-08-25 16:58:10 +07:00

15 KiB
Raw Blame History

name, description
name description
form-layout Use whenever building or editing a data-entry form in the ERP project (React/HTML forms, dialogs, wizards, settings pages, checkout-style forms, master-data screens, multi-step forms with line-item tables). Governs LAYOUT ONLY — field widths, grouping, column splits, vertical rhythm, label/input/helper placement, validation-state placement, checkbox/radio group layout, embedded data-table layout, wizard/stepper layout, and action-bar layout. Does not govern colors, fonts, border-radius, or other visual styling. Trigger this any time a new form, form section, form field, data table inside a form, or multi-step form flow is added or restructured, even if the user only says "add a field" or "build a form" without mentioning layout explicitly.

Form Layout

Layout rules for data-entry forms, derived from this project's reference forms (a checkout-style form and dense ERP entry forms — Journal Entry, Sales Invoice). These rules are about structure and grid, not visual style (color, weight, radius, shadows belong to the design system, not this skill).

Every field, group, section, table, and row decision should be made by walking the steps below, in order.

1. Pick the base grid for the form

Look at field count and density first — it decides the base grid for the whole form:

Form type Base grid
Short, linear form (≤810 fields, e.g. checkout, a settings dialog) Single column; multi-column rows only where §3 applies to a specific short-field group
Dense ERP entry form (master data, journal entry, invoice — many fields grouped by section) Two-column grid by default. Every field is placed into the left or right column of the current row. A field with no natural pair leaves the opposite column empty rather than stretching full width.

Once a form picks a base grid, stay consistent — don't mix an ad-hoc single column with an ad-hoc two-column region without a section boundary between them.

Full-width elements (§5 section headers, §6 tables, §7 textareas, §9 compound fields) always break out of the two-column grid regardless of which base grid is active.

2. Vertical structure of one field

Every field is a fixed vertical stack, top to bottom, with no steps skipped or reordered:

  1. Label — own line, directly above the input, tight gap, optionally suffixed with a required-marker (*) with no extra spacing added around it.
  2. Input — the control itself.
  3. Status line (optional, only one at a time) — sits directly under the input, same width as the input, in this priority order if multiple could apply: error message > helper/instructional text > success confirmation. Never stack more than one status line under a single field.

The label-to-input gap must be visibly smaller than the gap between one field's status line (or input, if no status line) and the next field's label — this is what makes fields read as self-contained units instead of a blurred list.

3. Multi-column field rows (row-level grouping)

Independent of the base grid (§1), some fields are grouped into one explicit row because the data itself is naturally short and multi-part:

  • Unequal column widths are correct when the data is unequal in length. City/State/Zip is not three equal thirds; City is widest, State (a dropdown) is medium, Zip is narrowest. Date/Time/Date triplets (e.g. Date, Posting Time, Payment Due Date) can split evenly since each is a similarly-sized control.
  • Every field in the row keeps its own label directly above it (per §2) unless the row is a genuinely single concept sharing one collective label (e.g. "Full name" over First/Last).
  • All inputs in a row share the same height and top edge.
  • On a two-column base grid (§1), a 3+ field row spans across both grid columns as its own full-width row — don't try to cram a 3-column group into a single grid column.

4. Two-column grid mechanics (dense ERP forms)

When the base grid is two-column (§1):

  • Fields are placed in the order they'd be read, filling left-then-right within each row, top to bottom — this is the same order screen readers and keyboard tab order should follow.
  • A field with a natural pair (e.g. Entry Type / From Template, Series / Company, Patient / Customer) sits with its pair in one row.
  • A field with no pair (e.g. a single Posting Date after Series/Company) still occupies the left column and leaves the right column of that row empty — do not stretch it to full width just to fill the space. Stretching to full width is reserved for the explicit full-width elements in §5–§9.
  • Both columns use identical widths and identical label/input/status structure (§2); only the content differs.
  • A section boundary (§5) can change the row's field pairing but the two-column mechanic continues underneath every section header.

5. Section headers

  • A section header (e.g. "Accounting Entries", "Reference", "Printing Settings", "More Information", "Accounting Dimensions", "Customer PO Details", "Address and Contact") is bold text, full width — it spans both columns of a two-column grid, never sits inside a single column.
  • Gap above a section header uses the largest rhythm gap (§8), separating it from the previous section's last row.
  • Gap below a section header uses the label-to-input gap (§2), binding it tightly to the first row of fields it introduces.
  • A section header never has its own input — it is a pure divider/label for the group beneath it.

6. Embedded data tables (line items / entry grids)

Some ERP forms embed an editable table (e.g. "Accounting Entries" with Account/Party Type/Party/Debit/Credit rows). Layout rules:

  • The table is a full-width element, breaking out of the two-column grid like a section header.
  • Column header row: short uppercase labels, left-aligned for text/identifier columns (NO., ACCOUNT, PARTY TYPE, PARTY), right-aligned for numeric columns (DEBIT, CREDIT) — numeric alignment must match the alignment of the values in the rows below it.
  • Each row: optional leading checkbox (row selection), then the data cells in the same alignment as their header, then a trailing per-row edit affordance in a fixed-width end column — the edit affordance column stays the same width on every row regardless of content length elsewhere.
  • Row-adding controls (e.g. "Add Multiple", "Add Row") sit directly below the table, left-aligned, as secondary-weight controls in their own row — not floated right, not mixed into the header row.
  • If the table has a totals/summary row (e.g. Total Debit / Total Credit), it sits in its own bounded row below the add-row controls, visually grouped with the table (same container), following the same left/right split as the action bar (§10): any secondary toggle (e.g. "Multi Currency" checkbox) on the left, the summary values on the right, right-aligned to match the numeric columns above.

7. Full-width text areas

  • A multi-line text input (e.g. "User Remark") always spans the full form width — both columns of a two-column grid — never confined to one column's width, since its content length is unpredictable and benefits from the extra width.
  • Label sits above it per §2; no side-by-side pairing is ever applied to a textarea.

8. Vertical rhythm

Define three consistent gap sizes and use them the same way everywhere on the form:

  1. Label → input (smallest gap): binds a label to its field.
  2. Input → status line (small, and reserved even when the status line is empty, so validation appearing/disappearing never shifts fields below it by more than this reserved height).
  3. One field row/group → next field row/group, and section header → previous section (largest gap): separates units of the form from each other.

This rhythm applies identically whether the base grid is single- or two-column (§1) — only the horizontal arrangement changes between the two, never the vertical spacing logic.

9. Compound fields (one logical field, many inputs)

Some "fields" are really one bounded control with several inputs inside it (e.g. a payment box with card number + expiry + CVV + zip all in one bordered container).

Use this pattern only when the sub-inputs are meaningless without each other and are always edited together:

  • One outer container (not a row of separate fields), full width, breaking out of the two-column grid like §5–§7.
  • Sub-inputs sit in a single internal row, widths proportional to expected content — the primary value gets the majority of the width, auxiliary values get narrow fixed-width slots.
  • Status/helper text for the whole compound field goes below the container once, not below individual sub-inputs.
  • A segmented toggle (e.g. a Yes/No pair rendered as two adjacent buttons acting as one control, as opposed to a labeled dropdown) is a compound field of two options: it occupies one column slot in the two-column grid (paired with its own label above, per §2), same width as a normal single field in that grid position — don't let it stretch full width unless it has no pair per §4.

10. Option groups (checkboxes / radio buttons)

Two distinct layouts, chosen by what the options represent:

  • Short categorical tags/multi-select (e.g. radio-technology checkboxes, a set of short mutually-relevant labels): lay out in a single horizontal row when there are ≤45 short options and the row fits the grid width; wrap to a multi-row grid if there are more. Equal, consistent spacing between options, tighter than the group-to-group gap (§8).
  • Independent settings/preference toggles (e.g. "Include Payment (POS)", "Is Return (Credit Note)", "Is Rate Adjustment Entry (Debit Note)"): stack vertically, one per row, each a fixed pair of control + label on one line. Use this layout whenever option labels are full phrases/sentences rather than short tags, or whenever an individual option may carry its own helper text below it (per §2's status-line pattern, scoped to that one option, indented to align under its label). Vertical stacking is also full-width, breaking out of the two-column grid.
  • In both layouts, each option is a fixed pair: control immediately followed by its label, never label-above-control.
  • A disabled option stays in its normal position (don't relocate or hide it) — position communicates "this exists but isn't available."

11. Multi-step / wizard forms

When a form is split into steps (e.g. Customer Details → Items & Pricing → Payments):

  • A stepper header sits at the top of the form, showing all steps as numbered nodes connected by a line, in left-to-right sequence order. The current step is visually distinguished from completed and upcoming steps, but this skill governs only its position (top of form, spanning the width reserved for it) and order (sequence order, never reordered).
  • Only the current step's fields are shown in the body; the body underneath the stepper follows every other rule in this document (base grid, sections, tables, etc.) exactly as if it were a standalone form.
  • Step navigation controls (Back / Next, or Back / Save on the final step) sit in a footer action bar per §10-style split: Back (secondary) on the left, the forward/primary action on the right. This footer is pinned to the bottom of the form's visible area so it stays reachable regardless of how long the current step's field list scrolls.
  • Going back a step must restore that step's field values and scroll position — a layout requirement, not just a data one: don't rebuild the step from a blank layout.
  • Split row: secondary/optional action (e.g. an opt-in checkbox) on one side, primary submit action on the other — don't stack them or center them together.
  • The primary action is the single visually dominant control in the row; any secondary control stays visually subordinate but does not shrink below a normal option-row size (§10).
  • This row gets the largest vertical gap (§8) above it, separating it clearly from the last field/section.

13. Validation and interaction states — placement, not color

State is communicated by what's added to the layout, not by recoloring alone:

  • Error: status-icon inside the input, right-aligned, vertically centered; error message on the status line below (§2), left-aligned under the input.
  • Success: status-icon inside the input, right-aligned, vertically centered.
  • Focus: no layout change to surrounding elements — focusing a field must never shift neighboring fields, columns, or table rows.
  • Disabled: field/row/option stays in its original position and width; never collapsed, hidden, or resized because it's disabled.

14. Responsive collapse

  • The two-column grid (§1, §4) collapses to a single stacked column below the defined breakpoint, left-column fields before right-column fields, in the same row order.
  • Multi-column field rows (§3) and compound fields (§9) collapse to a single stacked column, preserving left-to-right order top-to-bottom.
  • Embedded tables (§6) either scroll horizontally within their container or collapse each row into a stacked label/value list — pick one strategy per table and apply it consistently across the project, never mix per-table.
  • Option-group rows (§10) wrap to a multi-row grid before collapsing fully to one-per-line.
  • A stepper header (§11) may reduce to showing only the current step's label/number on narrow widths, but must preserve the sequence order and current-step position.
  • Never let collapse re-pair fields into different groupings than the base layout — grouping logic is fixed across breakpoints, only column count changes.

Checklist before finalizing any form or new field

  • Did you choose the base grid (single- vs two-column) from field density, per §1?
  • Does every field's width/position match its expected content and its pairing, per §1/§3/§4?
  • Are section headers, tables, textareas, and compound fields breaking out to full width, per §5–§7/§9?
  • Is every label-input-status stack using the three consistent gaps from §8?
  • Do embedded tables align numeric columns right and text columns left, with a fixed-width edit column?
  • Are table add-row controls below the table and any totals row split secondary-left/values-right?
  • Did you choose horizontal-tag vs vertical-toggle layout for each checkbox/radio group based on label length, per §10?
  • Does a wizard's stepper stay at the top, and its Back/Next footer stay pinned, per §11?
  • Do error/success states only add an icon + message, without moving neighboring fields?
  • Does the responsive layout preserve the same field groupings as the base layout, just fewer columns?