Skip to content
Backlit
Esc
navigateopen⌘Jpreview
On this page

Enum field

Display one or more values from a declared option set.

An enum field declares the complete set of accepted values and the label for each value. An option can also carry a semantic tone. The renderer shows the option label instead of the stored value.

API

fields.enum<Name extends string, const Choices extends readonly EnumOption[]>(
  name: Name,
  choices: Choices,
  options?: EnumFieldOptions
): EnumFieldBuilder<Name, Choices>
Option Input Result
label string Sets the text shown for the field.
description string Adds supporting text for the label.
displayVariant badge or text Selects the read-only presentation.
inputVariant select, radio, checkboxes Selects the form control.
cardinality one or many Selects one value or an array of values.

getOptionValues() and getOptionLabels() return the choice values and labels in declaration order. configure(options) returns a configured clone. clone() returns an independent copy with the same choices and options.

Each choice requires a value and label. Its optional tone can be neutral, info, success, warning, or danger.

Basic enum field

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

const orders = defineResource('orders', [
  fields.enum(
    'status',
    [
      { value: 'pending', label: 'Pending' },
      { value: 'shipped', label: 'Shipped' },
      { value: 'delivered', label: 'Delivered' },
    ],
    { label: 'Status' }
  ),
])

orders.view('detail', () =>
  datalist({ status: 'shipped' }).setFields(
    orders.pick('status')
  )
)

export default orders
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "orders",
    "name": "detail",
    "slots": {
      "content": [
        {
          "kind": "datalist",
          "fields": [
            {
              "kind": "enum",
              "name": "status",
              "label": "Status",
              "options": [
                {
                  "value": "pending",
                  "label": "Pending"
                },
                {
                  "value": "shipped",
                  "label": "Shipped"
                },
                {
                  "value": "delivered",
                  "label": "Delivered"
                }
              ]
            }
          ],
          "data": {
            "status": "shipped"
          }
        }
      ]
    }
  }
}

Description

Use a description to explain the meaning or selection rule for the option set.

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

const orders = defineResource('orders', [
  fields.enum(
    'status',
    [
      { value: 'pending', label: 'Pending' },
      { value: 'shipped', label: 'Shipped' },
    ],
    {
      label: 'Status',
      description: 'The current fulfilment state.',
    }
  ),
])

orders.view('detail', () =>
  datalist({ status: 'pending' }).setFields(
    orders.pick('status')
  )
)

export default orders
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "orders",
    "name": "detail",
    "slots": {
      "content": [
        {
          "kind": "datalist",
          "fields": [
            {
              "kind": "enum",
              "name": "status",
              "description": "The current fulfilment state.",
              "label": "Status",
              "options": [
                {
                  "value": "pending",
                  "label": "Pending"
                },
                {
                  "value": "shipped",
                  "label": "Shipped"
                }
              ]
            }
          ],
          "data": {
            "status": "pending"
          }
        }
      ]
    }
  }
}

Option tones

A tone gives an option semantic meaning. It is most visible when the field uses the badge display variant.

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

const orders = defineResource('orders', [
  fields.enum(
    'status',
    [
      { value: 'draft', label: 'Draft', tone: 'neutral' },
      {
        value: 'processing',
        label: 'Processing',
        tone: 'info',
      },
      {
        value: 'delivered',
        label: 'Delivered',
        tone: 'success',
      },
      {
        value: 'delayed',
        label: 'Delayed',
        tone: 'warning',
      },
      {
        value: 'cancelled',
        label: 'Cancelled',
        tone: 'danger',
      },
    ],
    { label: 'Status', displayVariant: 'badge' }
  ),
])

orders.view('detail', () =>
  datalist({ status: 'delayed' }).setFields(
    orders.pick('status')
  )
)

export default orders
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "orders",
    "name": "detail",
    "slots": {
      "content": [
        {
          "kind": "datalist",
          "fields": [
            {
              "kind": "enum",
              "name": "status",
              "label": "Status",
              "options": [
                {
                  "value": "draft",
                  "label": "Draft",
                  "tone": "neutral"
                },
                {
                  "value": "processing",
                  "label": "Processing",
                  "tone": "info"
                },
                {
                  "value": "delivered",
                  "label": "Delivered",
                  "tone": "success"
                },
                {
                  "value": "delayed",
                  "label": "Delayed",
                  "tone": "warning"
                },
                {
                  "value": "cancelled",
                  "label": "Cancelled",
                  "tone": "danger"
                }
              ],
              "displayVariant": "badge"
            }
          ],
          "data": {
            "status": "delayed"
          }
        }
      ]
    }
  }
}

Display variants

Use text to show option labels as text. Use badge to show each label as a status badge.

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

const options = [
  { value: 'pending', label: 'Pending', tone: 'warning' },
  { value: 'shipped', label: 'Shipped', tone: 'info' },
] as const

const orders = defineResource('orders', [
  fields.enum('textStatus', options, {
    label: 'Text',
    displayVariant: 'text',
  }),
  fields.enum('badgeStatus', options, {
    label: 'Badge',
    displayVariant: 'badge',
  }),
])

orders.view('detail', () =>
  datalist({
    textStatus: 'shipped',
    badgeStatus: 'shipped',
  }).setFields(orders.pick('textStatus', 'badgeStatus'))
)

export default orders
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "orders",
    "name": "detail",
    "slots": {
      "content": [
        {
          "kind": "datalist",
          "fields": [
            {
              "kind": "enum",
              "name": "textStatus",
              "label": "Text",
              "options": [
                {
                  "value": "pending",
                  "label": "Pending",
                  "tone": "warning"
                },
                {
                  "value": "shipped",
                  "label": "Shipped",
                  "tone": "info"
                }
              ],
              "displayVariant": "text"
            },
            {
              "kind": "enum",
              "name": "badgeStatus",
              "label": "Badge",
              "options": [
                {
                  "value": "pending",
                  "label": "Pending",
                  "tone": "warning"
                },
                {
                  "value": "shipped",
                  "label": "Shipped",
                  "tone": "info"
                }
              ],
              "displayVariant": "badge"
            }
          ],
          "data": {
            "textStatus": "shipped",
            "badgeStatus": "shipped"
          }
        }
      ]
    }
  }
}

Input variants

Use select for a compact control and radio for a visible single-choice set. Use checkboxes with many cardinality for multiple choices.

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

const options = [
  { value: 'pending', label: 'Pending' },
  { value: 'shipped', label: 'Shipped' },
] as const

const orders = defineResource('orders', [
  fields.enum('selectStatus', options, {
    label: 'Select',
    inputVariant: 'select',
  }),
  fields.enum('radioStatus', options, {
    label: 'Radio',
    inputVariant: 'radio',
  }),
  fields.enum('checkboxStatus', options, {
    label: 'Checkboxes',
    inputVariant: 'checkboxes',
    cardinality: 'many',
  }),
])

orders.view('detail', () =>
  datalist({
    selectStatus: 'pending',
    radioStatus: 'shipped',
    checkboxStatus: ['pending', 'shipped'],
  }).setFields(
    orders.pick(
      'selectStatus',
      'radioStatus',
      'checkboxStatus'
    )
  )
)

export default orders
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "orders",
    "name": "detail",
    "slots": {
      "content": [
        {
          "kind": "datalist",
          "fields": [
            {
              "kind": "enum",
              "name": "selectStatus",
              "label": "Select",
              "options": [
                {
                  "value": "pending",
                  "label": "Pending"
                },
                {
                  "value": "shipped",
                  "label": "Shipped"
                }
              ],
              "inputVariant": "select"
            },
            {
              "kind": "enum",
              "name": "radioStatus",
              "label": "Radio",
              "options": [
                {
                  "value": "pending",
                  "label": "Pending"
                },
                {
                  "value": "shipped",
                  "label": "Shipped"
                }
              ],
              "inputVariant": "radio"
            },
            {
              "kind": "enum",
              "name": "checkboxStatus",
              "cardinality": "many",
              "label": "Checkboxes",
              "options": [
                {
                  "value": "pending",
                  "label": "Pending"
                },
                {
                  "value": "shipped",
                  "label": "Shipped"
                }
              ],
              "inputVariant": "checkboxes"
            }
          ],
          "data": {
            "selectStatus": "pending",
            "radioStatus": "shipped",
            "checkboxStatus": [
              "pending",
              "shipped"
            ]
          }
        }
      ]
    }
  }
}

Cardinality

Use one for one stored value. Use many for an array of stored values. If you do not set cardinality, the field uses its single-value behavior.

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

const options = [
  { value: 'retail', label: 'Retail' },
  { value: 'wholesale', label: 'Wholesale' },
] as const

const customers = defineResource('customers', [
  fields.enum('primaryChannel', options, {
    label: 'Primary channel',
    cardinality: 'one',
  }),
  fields.enum('channels', options, {
    label: 'Channels',
    cardinality: 'many',
  }),
])

customers.view('detail', () =>
  datalist({
    primaryChannel: 'retail',
    channels: ['retail', 'wholesale'],
  }).setFields(customers.pick('primaryChannel', 'channels'))
)

export default customers
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "customers",
    "name": "detail",
    "slots": {
      "content": [
        {
          "kind": "datalist",
          "fields": [
            {
              "kind": "enum",
              "name": "primaryChannel",
              "cardinality": "one",
              "label": "Primary channel",
              "options": [
                {
                  "value": "retail",
                  "label": "Retail"
                },
                {
                  "value": "wholesale",
                  "label": "Wholesale"
                }
              ]
            },
            {
              "kind": "enum",
              "name": "channels",
              "cardinality": "many",
              "label": "Channels",
              "options": [
                {
                  "value": "retail",
                  "label": "Retail"
                },
                {
                  "value": "wholesale",
                  "label": "Wholesale"
                }
              ]
            }
          ],
          "data": {
            "primaryChannel": "retail",
            "channels": [
              "retail",
              "wholesale"
            ]
          }
        }
      ]
    }
  }
}

Option helpers

getOptionValues and getOptionLabels return typed tuples in declaration order. Use them to share the declared option set with validation or messages.

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

const status = fields.enum(
  'status',
  [
    { value: 'pending', label: 'Pending' },
    { value: 'shipped', label: 'Shipped' },
  ],
  { label: 'Status' }
)

const orders = defineResource('orders', [status])

orders.view('detail', (_ctx, view) => {
  const values = status.getOptionValues()
  const labels = status.getOptionLabels()

  view.setDescription(
    `${labels.join(' or ')} (${values.join(', ')})`
  )
  return datalist({ status: 'shipped' }).setFields(
    orders.pick('status')
  )
})

export default orders
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "orders",
    "name": "detail",
    "description": "Pending or Shipped (pending, shipped)",
    "slots": {
      "content": [
        {
          "kind": "datalist",
          "fields": [
            {
              "kind": "enum",
              "name": "status",
              "label": "Status",
              "options": [
                {
                  "value": "pending",
                  "label": "Pending"
                },
                {
                  "value": "shipped",
                  "label": "Shipped"
                }
              ]
            }
          ],
          "data": {
            "status": "shipped"
          }
        }
      ]
    }
  }
}

Clone

Use configure to reuse the choice set with different field options. The source field does not change.

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

const status = fields.enum(
  'status',
  [
    { value: 'pending', label: 'Pending', tone: 'warning' },
    { value: 'shipped', label: 'Shipped', tone: 'info' },
  ],
  { label: 'Status', displayVariant: 'text' }
)

const orders = defineResource('orders', [
  status.configure({ displayVariant: 'badge' }),
])

orders.view('detail', () =>
  datalist({ status: 'shipped' }).setFields(
    orders.pick('status')
  )
)

export default orders
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "orders",
    "name": "detail",
    "slots": {
      "content": [
        {
          "kind": "datalist",
          "fields": [
            {
              "kind": "enum",
              "name": "status",
              "label": "Status",
              "options": [
                {
                  "value": "pending",
                  "label": "Pending",
                  "tone": "warning"
                },
                {
                  "value": "shipped",
                  "label": "Shipped",
                  "tone": "info"
                }
              ],
              "displayVariant": "badge"
            }
          ],
          "data": {
            "status": "shipped"
          }
        }
      ]
    }
  }
}

All options

You can use option tones, a label, description, display variant, input variant, and cardinality on the same enum field.

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

const orders = defineResource('orders', [
  fields.enum(
    'status',
    [
      {
        value: 'pending',
        label: 'Pending',
        tone: 'warning',
      },
      { value: 'shipped', label: 'Shipped', tone: 'info' },
      {
        value: 'delivered',
        label: 'Delivered',
        tone: 'success',
      },
    ],
    {
      label: 'Status',
      description:
        'Select all states that apply to this order.',
      displayVariant: 'badge',
      inputVariant: 'checkboxes',
      cardinality: 'many',
    }
  ),
])

orders.view('detail', () =>
  datalist({ status: ['shipped', 'delivered'] }).setFields(
    orders.pick('status')
  )
)

export default orders
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "orders",
    "name": "detail",
    "slots": {
      "content": [
        {
          "kind": "datalist",
          "fields": [
            {
              "kind": "enum",
              "name": "status",
              "description": "Select all states that apply to this order.",
              "cardinality": "many",
              "label": "Status",
              "options": [
                {
                  "value": "pending",
                  "label": "Pending",
                  "tone": "warning"
                },
                {
                  "value": "shipped",
                  "label": "Shipped",
                  "tone": "info"
                },
                {
                  "value": "delivered",
                  "label": "Delivered",
                  "tone": "success"
                }
              ],
              "displayVariant": "badge",
              "inputVariant": "checkboxes"
            }
          ],
          "data": {
            "status": [
              "shipped",
              "delivered"
            ]
          }
        }
      ]
    }
  }
}

Fetched options

inputVariant also accepts lookupVia(...) and optionsVia(...). The enum’s static choices still define its display values. The input fetches choices from the lookup. See Lookup targets.

Was this page helpful?