Dynamically add an item to a dropdown list
type Task = {
value: string;
label: string;
mount: GoabDropdownItemMountType;
};
const DEFAULT_TASKS: Task[] = [
{ label: "Finish Report", value: "finish-report", mount: "append" },
{ label: "Attend Meeting", value: "attend-meeting", mount: "append" },
{ label: "Reply Emails", value: "reply-emails", mount: "append" },
];
const [tasks, setTasks] = useState<Task[]>(DEFAULT_TASKS);
const [newTask, setNewTask] = useState<string>("");
const [mountType, setMountType] = useState<string>("append");
const [selectedTask, setSelectedTask] = useState<string>("");
const [taskError, setTaskError] = useState<boolean>(false);
const [isReset, setIsReset] = useState<boolean>(false);
function onMountTypeChange(value: string | undefined) {
setMountType(value as string);
}
function addTask() {
if (newTask === "") {
setTaskError(true);
return;
}
setTaskError(false);
const task: Task = {
label: newTask,
value: newTask.toLowerCase().replace(" ", "-"),
mount: mountType as GoabDropdownItemMountType,
};
setTasks([...tasks, task]);
setNewTask("");
setIsReset(false);
}
function reset() {
setTasks(DEFAULT_TASKS);
setMountType("append");
setNewTask("");
setSelectedTask("");
setTaskError(false);
setIsReset(true);
}<GoabFormItem
requirement="required"
label="Name of item"
error={taskError ? "Please enter item name" : undefined}
helpText="Add an item to the dropdown list below">
<GoabInput
onChange={(event: GoabInputOnChangeDetail) => setNewTask(event.value)}
name="item"
value={newTask}
/>
</GoabFormItem>
<GoabFormItem mt="l" label="Add to">
<GoabRadioGroup
name="mountType"
onChange={(event: GoabRadioGroupOnChangeDetail) => onMountTypeChange(event.value)}
value={mountType}
orientation="horizontal">
<GoabRadioItem value="prepend" label="Start" />
<GoabRadioItem value="append" label="End" />
</GoabRadioGroup>
</GoabFormItem>
<GoabButtonGroup alignment="start" gap="relaxed" mt="l">
<GoabButton type="primary" onClick={addTask}>
Add new item
</GoabButton>
<GoabButton type="tertiary" onClick={reset}>
Reset list
</GoabButton>
</GoabButtonGroup>
<GoabDivider mt="l" />
<GoabFormItem mt="l" label="All items">
<div style={{ width: isReset ? "320px" : "auto" }}>
<GoabDropdown
key={tasks.length}
onChange={(event: GoabDropdownOnChangeDetail) =>
setSelectedTask(event.value as string)
}
value={selectedTask}
name="selectedTask">
{tasks.map(task => (
<GoabDropdownItem
key={task.value}
value={task.value}
mountType={task.mount}
label={task.label}
/>
))}
</GoabDropdown>
</div>
</GoabFormItem>Allow users to add new items to a dropdown list dynamically.
When to use
Use this pattern when:
- Users need to add custom options to a predefined list
- The list of options can grow based on user input
- You want to provide flexibility while maintaining structure
Considerations
- Use the
mountTypeprop to control where new items appear (prepend or append) - Validate input before adding to prevent empty or duplicate entries
- Provide a reset option to restore the original list
- Show clear feedback when items are added successfully