Canvas Design System
Main Site Tokens

Form Row

Consistent wrapper for form fields. Provides label, required indicator, helper text, and error states in a unified layout.

When to Use

Use Form Row when: Building forms with multiple fields that need consistent spacing, labels, and validation messaging. Combine with ws_input() and ws_select().
Don't use when: The field already has a built-in label via its own label option. Form Row is for adding external labels or grouping fields that share a label.

Basic Usage

We'll never share your email.

<?= ws_form_row(ws_input('email', ['type' => 'email', 'placeholder' => 'you@example.com']), [
    'label' => 'Email Address',
    'required' => true,
    'helper' => "We'll never share your email.",
]) ?>

Error State

Password must be at least 8 characters.

<?= ws_form_row(ws_input('password', ['type' => 'password']), [
    'label' => 'Password',
    'required' => true,
    'error' => 'Password must be at least 8 characters.',
]) ?>

Inline Layout

Set inline => true for a horizontal label + field layout.

<?= ws_form_row(ws_input('name', ['placeholder' => 'Jane Doe']), [
    'label' => 'Full Name',
    'inline' => true,
]) ?>

With Select

expand_more

Select your role in the workshop.

<?= ws_form_row(ws_select('role', [
    'facilitator' => 'Facilitator',
    'participant' => 'Participant',
    'observer' => 'Observer',
], ['placeholder' => 'Choose a role...']), [
    'label' => 'Role',
    'helper' => 'Select your role in the workshop.',
]) ?>

Form Layout Pattern

Combine multiple form rows in a vertical stack or a CSS Grid for multi-column forms.

<!-- Vertical form (default) -->
<form style="display: flex; flex-direction: column; gap: 20px; max-width: 480px;">
  <?= ws_form_row(ws_input('name'), ['label' => 'Name', 'required' => true]) ?>
  <?= ws_form_row(ws_input('email', ['type' => 'email']), ['label' => 'Email', 'required' => true]) ?>
  <?= ws_form_row(ws_input('notes', ['type' => 'textarea']), ['label' => 'Notes']) ?>
  <?= ws_button('Submit', ['variant' => 'primary', 'type' => 'submit']) ?>
</form>

<!-- Multi-column form -->
<form style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 640px;">
  <?= ws_form_row(ws_input('first'), ['label' => 'First Name']) ?>
  <?= ws_form_row(ws_input('last'), ['label' => 'Last Name']) ?>
  <?= ws_form_row(ws_input('email', ['type' => 'email']), ['label' => 'Email', 'columns' => 2]) ?>
</form>

Parameters

Option Type Default Description
labelstring''Row label text
requiredboolfalseShow red asterisk after label
helperstring''Helper text below field
errorstring''Error message (replaces helper, adds error state)
inlineboolfalseHorizontal label + field layout
columnsintnullGrid column span (for multi-column forms)
idstring''Element ID
classstring''Additional CSS classes

Files

FilePurpose
includes/components/helpers.phpws_form_row() helper function
includes/components/form-row.phpForm row template
includes/components/components.cssForm row styles