GrowSitedevelopers

Inputs and form fields

Field types, labels, options, limits and validation.

Two kinds of fields

A theme setting changes page content or appearance in the builder. Declare it in schema as text, range, color or another supported type. A form field is completed by a website visitor and submitted to the API. Declare it in the configuration.fields of a contact-form instance. These structures are not interchangeable.

Raw input, select, textarea and form tags are not currently rendered from Loom files by LoomMarkup. Do not use that markup alone as a working form. Use the instance workflow in the forms chapter.

A builder setting

json
{"type":"text","id":"title","label":"Heading","default":"Let's talk"}

Place this in a section or block settings array and read it through section.settings.title or block.settings.title. Its default fills the editor when no customer value exists. See the schema reference for all control types.

A visitor field

json
{"key":"email","label":"Email address","type":"email","required":true}

Place it in configuration.fields, not Loom schema. key identifies submitted data; label is visible to the visitor. You can improve a label while keeping a stable key. required is a boolean.

Type Use Server validation
text Name, company, short answer String up to 250 characters
textarea Message String up to 5000 characters
email Email address Valid email, up to 250 characters
tel Telephone number String up to 250 characters; no automatic country formatting
number Numeric response Numeric value
date Date YYYY-MM-DD format
select Single choice A configured option
checkbox Confirmation Required must be accepted; optional is boolean

Form number fields currently have no min/max/step settings, and dates have no configurable date bounds. Do not add these keys: the API rejects unknown configuration properties. Schema ranges apply to theme settings, not visitor fields.

Choice lists

json
{"key":"topic","label":"Topic","type":"select","required":true,"options":["Quote","Support","Other"]}

Options are strings, not schema-style value/label objects. The displayed string is also the submitted value. Changing options can affect validation of new responses. The shared public form currently renders a native select; the panel's custom select does not automatically replace it. Changing the public control requires updating the shared component, not adding Loom package markup.

Keys, limits and values

A form contains 1–30 fields. Keys begin with a lowercase letter and contain lowercase letters, digits, hyphens or underscores, up to 50 characters. Keys must be unique. website, instance_id and kind are reserved. Labels allow 120 characters. A list contains 1–30 options of up to 120 characters each.

The field contract only includes key, label, type, required and options. It has no separate default, placeholder, help text, upload, password or radio configuration. Visitors start with empty fields. The current input component derives its placeholder from the label.

Labels and appearance

The shared component wraps the control in a label, so clicking its name focuses the field. Shared styles provide an 8 px label gap and 16 px between field groups. Do not replace the label with a placeholder.

Example public styling in assets/theme.css:

css
.plugin-contact-form { display: grid; gap: 16px; }
.plugin-form-field { display: grid; gap: 8px; }
.plugin-form-field input:not([type="checkbox"]),
.plugin-form-field textarea,
.plugin-form-field select {
  min-height: 44px;
  padding: 12px;
  border: 1px solid #68756e;
  border-radius: 8px;
  background: #ffffff;
  color: #16221b;
}
.plugin-form-field :focus-visible { outline: 2px solid #16221b; outline-offset: 2px; }

Package CSS is scoped to its theme area. The form must be within that area to inherit these rules. Styling does not change validation or submission. Keep errors visible against the background.

Focus, active states and custom dropdowns

Each theme must provide visible keyboard focus and interaction states for its controls, including plugin search, comment forms, language switches and custom dropdowns. Use the theme's colors and geometry. :focus-visible marks keyboard focus, :focus-within marks a composite control while a child has focus, and :active is only the moment a control is pressed. Use aria-current, aria-selected, aria-expanded or details[open] for persistent states according to the component's semantics; do not represent selection using :active.

For a search input inside a rounded wrapper, draw one ring around the wrapper instead of a rectangular ring around the inner input:

css
.blog-section .blog-search:focus-within {
  outline: 2px solid var(--site-accent, currentColor);
  outline-offset: 0;
}
.blog-section .blog-search input:focus {
  outline: none;
  box-shadow: none;
}
.blog-section .blog-search button:focus-visible {
  outline: 2px solid var(--site-accent, currentColor);
  outline-offset: 3px;
}

Removing the input outline is safe here only because its wrapper has a visible replacement. Never apply outline: none globally. Keep the submit button's own keyboard focus visible so users can tell which action will run. Match field radii, prevent clipping of rings, and check contrast against both the field and page background. Browser autocomplete suggestions are browser UI; theme CSS does not style that popup.

GrowSite Skeleton uses its yellow accent, Paylio its configured accent and Victorie Vending orange focus styling in both color schemes. A pressed button has a subtle brightness change. Template-specific styling is packaged with each theme; it must also cover customer-added plugin blocks.

A custom dropdown must have an accessible trigger, a visible focus state, an expanded/open state, keyboard opening and closing, and a list that fits the viewport. A navigation dropdown contains links; a value picker uses appropriate selection semantics and keyboard behavior. Do not add role="menu" or role="listbox" without implementing their keyboard contracts. Style trigger, list, options, current selection, hover, disabled state and focus. Preserve application validation and stored values when using a shared form control.

For the shared Languages control use <gs-languages variant="dropdown"></gs-languages>. Its theme owns .gs-language-dropdown, summary and .gs-language-switch styling. The current language uses aria-current="true"; details[open] identifies the open dropdown. It supports Enter/Space on the trigger, Tab through links and Escape to close. See language switcher requirements for full integration and package examples.

Verify Tab, Shift+Tab, Enter, Space and Escape; mouse clicks; selected and disabled states; long option labels; many languages; and mobile widths. Confirm that focus stays visible without introducing horizontal page scrolling.

Verification

Click labels, navigate with the keyboard and check empty required fields, invalid emails and values outside configured options. An unchecked optional checkbox should submit false. Test long labels on mobile. Verify server behavior on a test published site.

See GS Loom UI components for the shared HTML contract, component variants, theme tokens and working examples.

Download Markdown copy
Results · 22
GS Loom UI components

Shared components, variants and theme styling.

Font catalog

Available fonts, previews and font declarations in GS Loom.

Menus and navigation

Create menus, connect links and style navigation.

Blog and comments

Blog and comments

SEO and plugin contracts

SEO and plugin contracts

Build your first theme

A complete package, installation and your first edit.

GS Loom Playground

Test themes locally without an API, database or upload.

Architecture and files

How author files become a customer website.

Schema and settings

Control types, default values and stable identifiers.

Blocks, targeting and order

Definitions, instances, nesting and static blocks.

Preview editing

Connect text, cards, images and icons to the builder.

Text and headings

From schema to text editing, typography and persistence.

Buttons and links

Labels, destinations, colors, dimensions and accessible states.

Inputs and form fields

Field types, labels, options, limits and validation.

Forms step by step

Instances, site binding, submission and error handling.

Cards, icons, images and badges

Container appearance, icon sizes and media editing.

Dynamic sources

Site data, page context and fallback values.

Layouts and shared settings

Section groups, global configuration and page templates.

Languages and translations

Starter languages, customer-added languages and AI translations.

Snippets, CSS and assets

Reusable markup, responsive styling and safe URLs.

Testing, import and updates

Validate a package and release it while preserving customer data.

Capabilities and limits

The supported GS Loom contract and working with AI.