Getting StartedComponentsDesign TokensThemingTheme SynthesizerFrameworksAccessibilityUtilitiesServer RenderingBrowser SupportContributingChangelogApp ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbarAnchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree ViewAccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual ListActivity HeatmapAnimated NumberBadgeBar ListChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveformBlockquoteCode BlockCode GroupGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriterButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerField ListFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree SelectAlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip
ARC UIARC Radiant Components
v4.9DocsComponentsTokensSynthesizer
Getting StartedFrameworksServer RenderingDesign TokensThemingTheme SynthesizerTypographyUtilitiesAll ComponentsAccessibilityBrowser SupportChangelogContributingStatsApp ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbarAnchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree ViewAccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual ListActivity HeatmapAnimated NumberBadgeBar ListChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveformBlockquoteCode BlockCode GroupGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriterButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerField ListFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree SelectAlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip

Field List

A repeating set of form rows the user can add to, remove from and reorder.

ComponentsField List
inputinteractive
<arc-field-list>

Overview

FieldList is for a form field that repeats: the options of a poll, the levels of a scale, a list of email addresses. Each row is an `<arc-field-row>` holding whatever inputs it needs, with a handle to reorder it and a button to remove it, and the list adds an Add button below. **Your application owns the rows.** Render them from your own array. The list never adds, removes or moves an element itself: it fires `arc-add`, `arc-remove` (with the `index`) and `arc-move` (with `from` and `to`), and you update your array. Keeping a single copy of the data means nothing can drift out of step. Everything around the data is the list's job: `min` and `max`, reordering by keyboard (the arrow keys on a row's handle) and by dragging, putting focus back where the user expects after each change, and a spoken confirmation of every change for screen reader users. The rows are plain light DOM, so their inputs submit with the surrounding form as they are named.

Guidelines

When to use

  • Give the list a `label` and each row a `label` ("Option 2") so controls read as "Remove Option 2"
  • Update your array on arc-add, arc-remove and arc-move; the rows follow when you re-render
  • Set `min` to the fewest rows the form can accept, so the last required row cannot be removed

When not to use

  • Do not add, remove or reorder rows in the DOM behind the list's back while a change it asked for is pending
  • Do not use it for a fixed number of fields; plain inputs are clearer

Features

  • Add, remove and reorder rows of any inputs
  • Reorder with the arrow keys on a row handle, or by dragging it
  • `min` and `max`, which disable Remove and Add at the limits
  • Focus follows the change: into a new row, onto a moved row, onto the row that took a removed one's place
  • Each change announced in a polite live region; each control named after its row
  • Your array stays the only copy: the list asks, your code changes it

Preview

Usage

This component requires JavaScript. No pure HTML/CSS version is available. Use the Web Component directly or a framework wrapper.

<arc-field-list label="Options" add-label="Add option" min="2" max="6">
  <arc-field-row label="Option 1"><arc-input label="Option 1" name="option" value="Yes"></arc-input></arc-field-row>
  <arc-field-row label="Option 2"><arc-input label="Option 2" name="option" value="No"></arc-input></arc-field-row>
</arc-field-list>

<script>
  // The list asks; your code changes the rows.
  const list = document.querySelector('arc-field-list');
  list.addEventListener('arc-add', () => { /* append a row to your data and re-render */ });
  list.addEventListener('arc-remove', (e) => { /* remove row e.detail.index */ });
  list.addEventListener('arc-move', (e) => { /* move row e.detail.from to e.detail.to */ });
</script>

API

labelstring''
Accessible name for the group of rows, such as "Options".
add-labelstring'Add'
Text of the Add button, exactly as given. The plus sign before it is an icon, not part of the text, so add-label="Option" reads "Option" with a + beside it.
readonlybooleanfalse
Show the rows without their controls: no Add button, no handles, no Remove buttons. For a fixed set that should look like the editable one, such as a taught question's options.
minnumber0
The fewest rows allowed. Remove is disabled at this count.
maxnumber0
The most rows allowed. Add is disabled at this count. Unset is unlimited.

Events

arc-add
The user asked for a new row. Append one to your array; focus moves into it when it renders.
arc-removedetail:{ value: number, index: number }
The user asked to remove the row at index. Remove it from your array.
arc-movedetail:{ value: number, from: number, to: number }
The user moved the row at from to to (also value). Move it in your array; focus follows it.

FieldRow

<arc-field-row>

One row: your inputs, with a handle to reorder the row and a button to remove it.

labelstring''
What this row is called in its controls' names, such as "Option 2". Defaults to "Row" and its position.

Methods

focusFirstField()
Focus the first field in the row, as after it was just added.
focusHandle()
Focus the handle, as after the row was moved.

See Also