Skip to content
Backlit
Esc
navigateopen⌘Jpreview
On this page

Text field

Display a string as plain text or a common contact value.

A text field declares a string value. Use a format to say what the string is: an email address, a URL, a phone number, or Markdown. The renderer controls the final presentation and interaction.

API

fields.text<Name extends string>(
  name: Name,
  options?: TextFieldOptions
): TextFieldBuilder<Name>
Option Input Result
label string Sets the text shown for the field.
description string Adds supporting text for the label.
format email, url, phone, or markdown Says what the string is.
inputVariant input or textarea Refines the form control.

configure(options) returns a configured clone. clone() returns an independent copy with the same options.

If you do not provide a label, the protocol uses an empty string. It leaves other unset options out of the field node.

Basic text field

Pass the record key to fields.text and add the label shown by the renderer.

import {
  datalist,
  defineResource,
  fields,
} from '@backlit/sdk'

const customers = defineResource('customers', [
  fields.text('name', { label: 'Name' }),
])

customers.view('detail', () =>
  datalist({ name: 'A. Customer' }).setFields(
    customers.pick('name')
  )
)

export default customers
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "customers",
    "name": "detail",
    "slots": {
      "content": [
        {
          "kind": "datalist",
          "fields": [
            {
              "kind": "text",
              "name": "name",
              "label": "Name"
            }
          ],
          "data": {
            "name": "A. Customer"
          }
        }
      ]
    }
  }
}

Description

A description supplies supporting text for the field label.

import {
  datalist,
  defineResource,
  fields,
} from '@backlit/sdk'

const orders = defineResource('orders', [
  fields.text('note', {
    label: 'Courier note',
    description: 'This text appears on the shipping label.',
  }),
])

orders.view('detail', () =>
  datalist({
    note: 'Leave the parcel at reception.',
  }).setFields(orders.pick('note'))
)

export default orders
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "orders",
    "name": "detail",
    "slots": {
      "content": [
        {
          "kind": "datalist",
          "fields": [
            {
              "kind": "text",
              "name": "note",
              "label": "Courier note",
              "description": "This text appears on the shipping label."
            }
          ],
          "data": {
            "note": "Leave the parcel at reception."
          }
        }
      ]
    }
  }
}

Formats

Text supports four formats. A format says what the string is. The value on the wire is the string in every case.

Format Use Form control
email An email address. A single line with the email keyboard.
url An absolute or application URL. A single line with the URL keyboard.
phone A telephone number. A single line with the phone keyboard.
markdown Markdown source. A textarea beside a rendered preview.

A markdown value renders in the browser. The built-in renderer does not render raw HTML inside the source. A host replaces the renderer through the blocks.markdown registry entry to use its own pipeline and components.

The editor preview uses the blocks['markdown-preview'] registry entry. When you do not set it, the preview uses blocks.markdown. Set it when the preview must show more than the body: for example, an email with its subject and template around the source. The preview renders inside the form, and the useFormValues hook from @backlit/ui returns the current values of the other fields.

<BacklitApp {...appProps} blocks={{ 'markdown-preview': NewsletterPreview }}>
  {children}
</BacklitApp>

NewsletterPreview receives a source string. Extensions can supply the same registry entry. The host’s entry takes precedence over extension entries.

import {
  datalist,
  defineResource,
  fields,
} from '@backlit/sdk'

const customers = defineResource('customers', [
  fields.text('email', {
    label: 'Email',
    format: 'email',
  }),
  fields.text('website', {
    label: 'Website',
    format: 'url',
  }),
  fields.text('phone', {
    label: 'Phone',
    format: 'phone',
  }),
  fields.text('notes', {
    label: 'Notes',
    format: 'markdown',
  }),
])

customers.view('detail', () =>
  datalist({
    email: '[email protected]',
    website: 'https://example.com',
    phone: '+1 202 555 0147',
    notes:
      'Prefers **email**. Ships to:\n\n- the office\n- the warehouse',
  }).setFields(
    customers.pick('email', 'website', 'phone', 'notes')
  )
)

export default customers
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "customers",
    "name": "detail",
    "slots": {
      "content": [
        {
          "kind": "datalist",
          "fields": [
            {
              "kind": "text",
              "name": "email",
              "label": "Email",
              "format": "email"
            },
            {
              "kind": "text",
              "name": "website",
              "label": "Website",
              "format": "url"
            },
            {
              "kind": "text",
              "name": "phone",
              "label": "Phone",
              "format": "phone"
            },
            {
              "kind": "text",
              "name": "notes",
              "label": "Notes",
              "format": "markdown"
            }
          ],
          "data": {
            "email": "[email protected]",
            "website": "https://example.com",
            "phone": "+1 202 555 0147",
            "notes": "Prefers **email**. Ships to:\n\n- the office\n- the warehouse"
          }
        }
      ]
    }
  }
}

Input variants

Input variants affect forms. The format picks the control. An input variant refines it: input for one line, textarea for multiple lines. A textarea on a markdown field edits the source with no preview. Input variants do not change the read-only value in a datalist or table.

import {
  datalist,
  defineResource,
  fields,
} from '@backlit/sdk'

const customers = defineResource('customers', [
  fields.text('name', {
    label: 'Name',
    inputVariant: 'input',
  }),
  fields.text('notes', {
    label: 'Notes',
    inputVariant: 'textarea',
  }),
])

customers.view('detail', () =>
  datalist({
    name: 'A. Customer',
    notes: 'Prefers email contact.',
  }).setFields(customers.pick('name', 'notes'))
)

export default customers
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "customers",
    "name": "detail",
    "slots": {
      "content": [
        {
          "kind": "datalist",
          "fields": [
            {
              "kind": "text",
              "name": "name",
              "label": "Name",
              "inputVariant": "input"
            },
            {
              "kind": "text",
              "name": "notes",
              "label": "Notes",
              "inputVariant": "textarea"
            }
          ],
          "data": {
            "name": "A. Customer",
            "notes": "Prefers email contact."
          }
        }
      ]
    }
  }
}

Clone

Use configure to reuse a declaration with different options. It clones the field first, so the original field does not change.

import {
  datalist,
  defineResource,
  fields,
} from '@backlit/sdk'

const email = fields.text('email', {
  label: 'Email',
  format: 'email',
})
const customers = defineResource('customers', [
  email.configure({ label: 'Work email' }),
])

customers.view('detail', () =>
  datalist({ email: '[email protected]' }).setFields(
    customers.pick('email')
  )
)

export default customers
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "customers",
    "name": "detail",
    "slots": {
      "content": [
        {
          "kind": "datalist",
          "fields": [
            {
              "kind": "text",
              "name": "email",
              "label": "Work email",
              "format": "email"
            }
          ],
          "data": {
            "email": "[email protected]"
          }
        }
      ]
    }
  }
}

All options

You can use a label, description, format, and input variant on the same text field.

import {
  datalist,
  defineResource,
  fields,
} from '@backlit/sdk'

const customers = defineResource('customers', [
  fields.text('email', {
    label: 'Email',
    description: 'The address used for order updates.',
    format: 'email',
    inputVariant: 'input',
  }),
])

customers.view('detail', () =>
  datalist({ email: '[email protected]' }).setFields(
    customers.pick('email')
  )
)

export default customers
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "customers",
    "name": "detail",
    "slots": {
      "content": [
        {
          "kind": "datalist",
          "fields": [
            {
              "kind": "text",
              "name": "email",
              "label": "Email",
              "description": "The address used for order updates.",
              "format": "email",
              "inputVariant": "input"
            }
          ],
          "data": {
            "email": "[email protected]"
          }
        }
      ]
    }
  }
}

Was this page helpful?