MenuChevron Down
TagsField - Docs - Artefact

TagsField

Forms
Smart auto-detect

A component that allows users to enter multiple tags as a list, with the same label / helper text / error text conventions as Field.

Usage

React
Hono
Press Enter to add a tag
import { TagsField } from "../components/ui";

export default function MyPage() {
  return (
    <TagsField
      label="Skills"
      helperText="Press Enter to add a tag"
      defaultValue={["React", "Hono"]}
      onValueChange={(details) => console.log(details.value)}
    />
  );
}

Behaviour

  • Enter commits the current input text as a new tag (duplicates are ignored) and clears the input.
  • Backspace on an empty input removes the last tag.
  • Clicking a tag's delete trigger (rendered by Items) removes that specific tag.
  • Clicking anywhere in the control that isn't a tag focuses the input.

Variants and sizes

variant ("outline" | "subtle" | "surface", default "outline") and size ("xs" | "sm" | "md" | "lg", default "md") control appearance, matching the conventions used by Field/Input.

<TagsField variant="subtle" size="lg" defaultValue={["React"]} />

Composition

The default label/helperText/errorText props cover most cases, but the underlying parts are also exported for custom layouts:

import { TagsField } from "../components/ui";

<TagsField.Root defaultValue={["React", "Hono"]}>
  <TagsField.Label>Skills</TagsField.Label>
  <TagsField.Control>
    <TagsField.Items />
    <TagsField.Input placeholder="Add a skill…" />
  </TagsField.Control>
  <TagsField.ClearTrigger>Clear all</TagsField.ClearTrigger>
  <TagsField.HiddenInput name="skills" />
</TagsField.Root>;

CMS Page Builder

This component is available as a tagsField block in the Page Builder (content/pages/*.json):

{
  "type": "tagsField",
  "label": "Amenities",
  "defaultValue": ["WiFi", "Fireplace", "Hot Tub"]
}

Props

PropTypeDefaultDescription
valuestring[]-Controlled tags (forces interactive mode).
defaultValuestring[]-Initial tags.
inputValuestring-Controlled text-input value (forces interactive mode).
defaultInputValuestring-Initial text-input value.
labelChild-The field's label.
helperTextChild-Helper text shown below the tags.
errorTextChild-Error text shown when invalid is set.
invalidboolean-Forces the invalid state, showing errorText.
disabledboolean-Disables the input and delete/clear triggers.
readOnlyboolean-Hides the text input, preventing new tags from being added.

| variant | `"outline" \ | "subtle" \ | "surface"` | "outline" | Visual style. |

| size | `"xs" \ | "sm" \ | "md" \ | "lg"` | "md" | Control size. |

| name | string | - | Form field name for the hidden submit input (comma-joined tags). |

| dir | `"ltr" \ | "rtl"` | - | Text direction. |

| onValueChange | (details: { value: string[] }) => void | - | Fires when a tag is added or removed (forces interactive mode). | | onInputValueChange | (details: { inputValue: string }) => void | - | Fires as the text input changes (forces interactive mode). | | interactive | boolean | - | Forces or forbids hydration as an island. |

CMS Configuration

- label: Tags Field
  name: tagsField
  widget: object
  fields:
    - { label: Label, name: label, widget: string, required: false }
    - { label: Helper Text, name: helperText, widget: string, required: false }
    - { label: Error Text, name: errorText, widget: string, required: false }
    - { label: Default Tags, name: defaultValue, widget: list, required: false }

Hydration

Tier-2: Hydrates when value, inputValue, defaultValue, defaultInputValue, onValueChange, or onInputValueChange is present.