Chip Field
A specialized input field that lets users create and manage a collection of chips representing freeform text values or selections.
Usage
forge-chip-field wraps a slotted <input> and shares the same field frame as a text field (variant, theme, shape, density, label-position, invalid, required, disabled) plus its own add-on-blur. The field itself doesn’t create chips — it fires forge-chip-field-member-added and forge-chip-field-member-removed, and the app appends or removes a chip with slot="member" in response. Use it for freeform, removable entries like tags or recipients; for a single value, use a plain text field, and for entries chosen from a known list, pair it with autocomplete instead of accepting arbitrary text.
Rules
Adding chips
Type a value and press Enter to fire forge-chip-field-member-added with the entered text; append a forge-chip with slot="member" in response, and remove it on forge-chip-field-member-removed.
A chip field with support text guiding how to add a tag.
<forge-chip-field>
<label slot="label" for="tag-input">
Tags
</label>
<input type="text" id="tag-input" />
<div slot="support-text">
Press enter to create a tag
</div>
</forge-chip-field>
<script type="module">
const chipField = document.querySelector("forge-chip-field");
chipField?.addEventListener("forge-chip-field-member-added", ({ detail: name }) => {
const chip = document.createElement("forge-chip");
chip.setAttribute("slot", "member");
chip.type = "field";
chip.dense = true;
chip.value = name;
chip.textContent = name;
chip.addEventListener("forge-chip-delete", () => {
if (chip.disabled) {
return;
}
chip.remove();
});
chipField.appendChild(chip);
});
chipField?.addEventListener("forge-chip-field-member-removed", ({ detail }) => {
chipField.removeChild(detail);
});
</script>With autocomplete
Nest a chip field inside a forge-autocomplete to confirm each typed value against a filtered list of suggestions instead of accepting arbitrary free text.
A chip field nested inside an autocomplete, with a dropdown trigger and clear button.
<forge-autocomplete mode="stateless">
<forge-chip-field popover-icon show-clear>
<label slot="label" for="tag-input">
Tags
</label>
<input type="text" id="tag-input" autocomplete="off" role="combobox" aria-live="polite" aria-atomic aria-haspopup aria-autocomplete="list" aria-controls="forge-aria-controls-placeholder">
</forge-chip-field>
</forge-autocomplete>
<script type="module">
const US_STATES = [
{ label: "Alabama", value: "AL" },
{ label: "Alaska", value: "AK" },
{ label: "Arizona", value: "AZ" },
{ label: "Arkansas", value: "AR" },
{ label: "California", value: "CA" },
{ label: "Colorado", value: "CO" },
{ label: "Connecticut", value: "CT" },
{ label: "Delaware", value: "DE" },
{ label: "Florida", value: "FL" },
{ label: "Georgia", value: "GA" },
{ label: "Hawaii", value: "HI" },
{ label: "Idaho", value: "ID" },
{ label: "Illinois", value: "IL" },
{ label: "Indiana", value: "IN" },
{ label: "Iowa", value: "IA" },
{ label: "Kansas", value: "KS" },
{ label: "Kentucky", value: "KY" },
{ label: "Louisiana", value: "LA" },
{ label: "Maine", value: "ME" },
{ label: "Maryland", value: "MD" },
{ label: "Massachusetts", value: "MA" },
{ label: "Michigan", value: "MI" },
{ label: "Minnesota", value: "MN" },
{ label: "Mississippi", value: "MS" },
{ label: "Missouri", value: "MO" },
{ label: "Montana", value: "MT" },
{ label: "Nebraska", value: "NE" },
{ label: "Nevada", value: "NV" },
{ label: "New Hampshire", value: "NH" },
{ label: "New Jersey", value: "NJ" },
{ label: "New Mexico", value: "NM" },
{ label: "New York", value: "NY" },
{ label: "North Carolina", value: "NC" },
{ label: "North Dakota", value: "ND" },
{ label: "Ohio", value: "OH" },
{ label: "Oklahoma", value: "OK" },
{ label: "Oregon", value: "OR" },
{ label: "Pennsylvania", value: "PA" },
{ label: "Rhode Island", value: "RI" },
{ label: "South Carolina", value: "SC" },
{ label: "South Dakota", value: "SD" },
{ label: "Tennessee", value: "TN" },
{ label: "Texas", value: "TX" },
{ label: "Utah", value: "UT" },
{ label: "Vermont", value: "VT" },
{ label: "Virginia", value: "VA" },
{ label: "Washington", value: "WA" },
{ label: "West Virginia", value: "WV" },
{ label: "Wisconsin", value: "WI" },
{ label: "Wyoming", value: "WY" }
];
const autocomplete = document.querySelector("forge-autocomplete");
const chipField = document.querySelector("forge-chip-field");
const selectedValues = [];
function addMember(value) {
if (!chipField) {
return;
}
const chip = document.createElement("forge-chip");
chip.setAttribute("slot", "member");
chip.type = "field";
chip.dense = true;
chip.value = value;
chip.textContent = value;
chip.addEventListener("forge-chip-delete", () => {
chip.remove();
const index = selectedValues.indexOf(value);
if (index !== -1) {
selectedValues.splice(index, 1);
}
});
chipField.appendChild(chip);
}
if (autocomplete) {
autocomplete.filter = (filterText) => {
const remaining = US_STATES.filter(({ value }) => !selectedValues.includes(value));
return remaining.filter(({ label }) => label.toLowerCase().includes(filterText.toLowerCase()));
};
autocomplete.addEventListener("forge-autocomplete-select", (event) => {
const { detail } = event;
if (!selectedValues.includes(detail.value)) {
addMember(detail.value);
selectedValues.push(detail.value);
}
});
}
</script>Confirm on blur
Set add-on-blur to confirm a chip when focus leaves the field, not just on Enter.
add-on-blur confirms a chip when focus leaves the field, not just on Enter.
<forge-chip-field add-on-blur>
<label slot="label" for="chip-field-blur-input">
Tags
</label>
<input type="text" id="chip-field-blur-input" />
<forge-chip slot="member" type="field" dense value="design">
design
</forge-chip>
</forge-chip-field>Disabled
Set disabled to exclude the chip field, and its existing members, from interaction.
A disabled chip field with existing members.
<forge-chip-field disabled>
<label slot="label" for="chip-field-disabled-input">
Tags
</label>
<input type="text" id="chip-field-disabled-input" />
<forge-chip slot="member" type="field" dense disabled value="design">
design
</forge-chip>
<forge-chip slot="member" type="field" dense disabled value="research">
research
</forge-chip>
</forge-chip-field>A specialized input field component that allows users to create and manage a collection of chips representing text values or selections. Use a chip field when you want to allow users to input multiple discrete items, such as tags, categories, or selections from a predefined list. Prefer alternatives such as a select or autocomplete when dealing with a large number of options or when single selection is sufficient.
import "@tylertech/forge/chip-field";| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
addOnBlur | add-on-blur | boolean | false | Whether or not to add chip when blur event |
popoverTargetElement | — | boolean | — | The target element for the popover. |
labelPosition | label-position | FieldLabelPosition | "inset" | The position of the label relative to the field. |
labelAlignment | label-alignment | FieldLabelAlignment | "start" | The alignment of the label relative to the field. |
invalid | invalid | boolean | false | Whether the field is in an invalid state. |
required | required | boolean | false | Whether the field is required. |
optional | optional | boolean | false | Whether the field is optional. |
disabled | disabled | boolean | false | Whether the field is disabled. |
floatLabel | float-label | boolean | false | Whether the label should float above the field. Only applies when the label is inset. |
variant | variant | FieldVariant | "outlined" | The variant of the field. |
theme | theme | FieldTheme | "default" | The theme of the field. |
shape | shape | FieldShape | "default" | The shape of the field. |
density | density | FieldDensity | "default" | The density of the field. |
dense | dense | boolean | false | Whether the field is dense. |
popoverIcon | popover-icon | boolean | false | Whether the field has a popover icon. |
popoverExpanded | popover-expanded | boolean | false | Whether the field's popover is expanded. |
supportTextInset | support-text-inset | FieldSupportTextInset | "none" | The inset of the support text. |
| Name | Type | Description |
|---|---|---|
forge-button-toggle-select | CustomEvent<IButtonToggleSelectEventData> | Dispatches when the user toggles the button. |
forge-field-popover-icon-click | CustomEvent<void> | Dispatches when the user clicks the popover icon. |
| Name | Description |
|---|---|
(default) | The default/unnamed slot for the field's input. |
label | Renders its content as a positioned label. |
start | Typically reserved for content/icons that render logically before the default slot content. |
end | Typically reserved content/icons that render logically after the default slot content. |
accessory | Used for content such as a button that is logically connected to the field but should appear distinct from the input |
support-text | Used for content that provides additional information about the field. Aligns to the inline start of the field. |
support-text-end | Used for content that provides additional information about the field. Aligns to the inline end of the field. |
| Name | Description |
|---|---|
::part(root) | The root container element. |
::part(label) | The label element. |
::part(input) | The element containing the input slot. |
::part(start) | The element containing the start slot. |
::part(end) | The element containing the end slot. |
::part(popover-icon) | The popover icon element. |
::part(accessory) | The element containing the accessory slot. |
::part(support-text) | The support text element. |
::part(support-text-end) | The element containing the support text end slot. |
::part(outline) | The element containing the forge-focus-indicator element. |
::part(focus-indicator) | The focus indicator element. |
| Name | Description |
|---|---|
--forge-chip-field-member-spacing | The spacing between chip members. |
--forge-chip-field-content-spacing | The spacing around chips group. |
--forge-field-background | The background of the field surface. |
--forge-field-tonal-background | The background of the field surface in the tonal variant. |
--forge-field-tonal-background-hover | The background of the field surface in the tonal variant on hover. |
--forge-field-filled-background | The background of the field surface in the filled and raised variants. |
--forge-field-outline-style | The style of the field outline. |
--forge-field-outline-width | The width of the field outline. |
--forge-field-shape | The border radius of the field's corners. |
--forge-field-height | The height of the field in its default density. |
--forge-field-inset-height | The height of the field in its default density when the label is inset. |
--forge-field-padding-inline | The inline padding of the field. |
--forge-field-padding-inline-start | The inline start padding of the field. |
--forge-field-padding-inline-end | The inline end padding of the field. |
--forge-field-inner-padding-inline | The padding between elements slotted into the field. |
--forge-field-support-text-margin-block | The margin between the support text and the field. |
--forge-field-support-text-gap | The minimum gap between the support text and the support text end. |
--forge-field-support-text-padding-inline | The inline padding of the support text. |
--forge-field-support-text-padding-inline-start | The inline start padding of the support text. |
--forge-field-support-text-padding-inline-end | The inline end padding of the support text. |
--forge-field-label-margin-inline | The margin between the label and the field when the label is in an inline position. |
--forge-field-label-margin-block | The margin between the label and the field when the label is in the block start position. |
--forge-field-required-padding | The padding between the required indicator and the label. |
--forge-field-required-content | The content of the required indicator. |
--forge-field-optional-padding | The padding between the optional indicator and the label. |
--forge-field-optional-content | The content of the optional indicator. |
--forge-field-multiline-resize | The direction the field can be resized when multiline. |
--forge-field-multiline-min-inline-size | The minimum inline size the field can be resized to when multiline. |
--forge-field-multiline-max-inline-size | The maximum inline size the field can be resized to when multiline. |
--forge-field-multiline-min-block-size | The minimum block size the field can be resized to when multiline. |
--forge-field-multiline-max-block-size | The maximum block size the field can be resized to when multiline. |
--forge-field-popover-icon-transition-duration | The duration of the popover icon animation. |
--forge-field-popover-icon-transition-timing | The timing function of the popover icon animation. |
--forge-field-popover-icon-open-rotation | The rotation of the popover icon when open. |
--forge-field-surface-animation-duration | The duration of background and outline animations. |
--forge-field-surface-animation-timing | The timing function of background and outline animations. |
--forge-field-surface-floating-animation-duration | The duration of the floating label animation. |
--forge-field-surface-floating-animation-timing | The timing function of the floating label animation. |
--forge-field-focus-indicator-width | The width of the focus indicator. |
--forge-field-disabled-opacity | The opacity of the field when disabled. |
--forge-field-disabled-background | The background of the field when disabled. |
| Name | Returns | Description |
|---|---|---|
click() | void | |
floatLabelWithoutAnimation(value) | void | Floats the label immediately. Only applies when the label is inset. |
Labeling
Give the field’s <input> an id and bind a <label> to it with a matching for attribute. Give each member chip a descriptive aria-label or aria-labelledby so a screen reader can announce what value it represents.
Keyboard interaction
Member chips must be reachable with the Left and Right arrow keys, with a distinct visual cue showing which chip is currently focused. Backspace and Delete should remove whichever chip currently has that keyboard focus.
Disabled state
When the field is disabled, the field itself and every member chip need to appear — and behave — disabled. A disabled field with interactive-looking chips is a common gap to check for.