Navigation
Inputs & Forms
Selection
Containers & Overlays
Form Repeat
Lays out fields, groups, repeated entries and the actions of a form.
Overview
FormRepeat lets people add, remove and reorder entries of the same shape, e.g. several email addresses. Every item needs a unique id for tracking and drag and drop.
Email Addresses
Add one or more email addresses
"use client";import {FormRepeat, Input} from "@brynlabs/fusion-ui";import React, {useState} from "react";type EmailAddress = {email: string;};export const SimpleExample = () => {const [emailAddresses, setEmailAddresses] = useState<EmailAddress[]>([]);return <FormRepeatlabel={"Email Addresses"}addLabel={"Add Email"}hint={"Add one or more email addresses"}value={emailAddresses}onChange={setEmailAddresses}newItem={() => ({email: ""})}>{({value, onChange}) => (<Inputvalue={value.email}onChange={change => onChange({...value, email: change})}placeholder={"email@example.com"}/>)}</FormRepeat>;};
Multiple fields with FormGroup
Use FormGroup for several fields per entry.
Expansion mode:
Multiple
Contacts
Add contact information
"use client";import {Checkbox, FormGroup, FormRepeat, FormSpacing, Input, Select} from "@brynlabs/fusion-ui";import React, {useState} from "react";type Contact = {name: string;email: string;};type ExpansionMode = "single" | "multiple";export const FormGroupExample = () => {const [contacts, setContacts] = useState<Contact[]>([]);const [expansionMode, setExpansionMode] = useState<ExpansionMode>("multiple");const [autoExpand, setAutoExpand] = useState(false);return (<FormSpacing><div style={{display: "flex", alignItems: "center", gap: "0.5rem", marginTop: "2rem"}}><p>Expansion mode:</p><Select<ExpansionMode>placeholder="Select expansion mode"value={expansionMode}values={["single", "multiple"]}mapValueToString={value => (value === "single" ? "Single" : "Multiple")}onChange={value => {if (value !== null) {setExpansionMode(value);}}}/></div><Checkboxlabel="Automatically expand new contacts"value={autoExpand}onChange={setAutoExpand}/><FormRepeatlabel="Contacts"addLabel="Add Contact"hint="Add contact information"value={contacts}onChange={setContacts}newItem={() => ({name: "", email: ""})}expansionMode={expansionMode}autoExpand={autoExpand}>{({value, onChange}) => (<FormGroupgroupLabel={value.name ? `Contact – ${value.name}` : "New Contact"}><FormSpacing><Inputlabel="Name"value={value.name}onChange={name => onChange({...value, name})}placeholder="John Doe"/><Inputlabel="Email"value={value.email}onChange={email => onChange({...value, email})}placeholder="john@example.com"/></FormSpacing></FormGroup>)}</FormRepeat></FormSpacing>);};
Custom button positions
FormRepeatChild places the reorder and delete buttons within your own layout.
Team Members
"use client";import {Checkbox, FormRepeat, FormRepeatChild, Input} from "@brynlabs/fusion-ui";import React, {useState} from "react";type TeamMember = {name: string;email: string;};export const FormRepeatChildExample = () => {const [teamMembers, setTeamMembers] = useState<TeamMember[]>([]);return (<FormRepeatlabel={"Team Members"}addLabel={"Add Team Member"}value={teamMembers}onChange={setTeamMembers}newItem={() => ({name: "", email: ""})}>{({value, onChange}) => (<FormRepeatChild>{({reorderButton, deleteButton, isExpanded, onExpandedChange}) => (<div style={{padding: "1rem", background: "gray"}}>{reorderButton}<Checkbox value={isExpanded} onChange={onExpandedChange} label={"Expanded"}></Checkbox>{isExpanded && (<Inputlabel={"Name"}value={value.name}onChange={change => onChange({...value, name: change})}placeholder={"Jane Smith"}/>)}{deleteButton}</div>)}</FormRepeatChild>)}</FormRepeat>);};

