= useCallback(
(event) => {
- if (!Array.isArray(value)) {
- const nextTarget = event.relatedTarget as Node | null;
- const movingInside =
- inputWrapperRef.current?.contains(nextTarget) ||
- refs.floating.current?.contains(nextTarget) ||
- resultsRef.current?.contains(nextTarget);
-
- if (!movingInside) {
- if (searchText !== value?.value) {
- restoreSearchToSelectedValue();
- }
- resetSearchQuery();
- closeResults();
- }
+ const nextTarget = event.relatedTarget as Node | null;
+ const movingInside =
+ inputWrapperRef.current?.contains(nextTarget) ||
+ refs.floating.current?.contains(nextTarget) ||
+ resultsRef.current?.contains(nextTarget);
+
+ if (!movingInside) {
+ syncSearchOnDismiss();
}
props.onBlur?.(event);
},
- [
- value,
- searchText,
- restoreSearchToSelectedValue,
- resetSearchQuery,
- closeResults,
- refs.floating,
- props.onBlur,
- ],
+ [syncSearchOnDismiss, refs.floating, props.onBlur],
);
const comboboxProps = {
@@ -622,7 +593,7 @@ export const AutocompleteInput = forwardRef<
open={isOpen}
className={classes.modal}
contentClassName={classes['modal-content']}
- onClose={dismissWithoutSelection}
+ onClose={syncSearchOnDismiss}
>
Date: Mon, 15 Jun 2026 10:07:09 +0200
Subject: [PATCH 3/3] fix: adjust to use changeInputValue
---
.changeset/autocomplete-input-contract.md | 12 ++++++++++++
.../AutocompleteInput/AutocompleteInput.tsx | 6 ++++--
2 files changed, 16 insertions(+), 2 deletions(-)
create mode 100644 .changeset/autocomplete-input-contract.md
diff --git a/.changeset/autocomplete-input-contract.md b/.changeset/autocomplete-input-contract.md
new file mode 100644
index 0000000000..61e98799b8
--- /dev/null
+++ b/.changeset/autocomplete-input-contract.md
@@ -0,0 +1,12 @@
+---
+"@sumup-oss/circuit-ui": patch
+---
+
+**AutocompleteInput:** emit `onSearch` when the search text is reset internally (on
+blur-restore, clear, and immersive modal dismiss), so consumers that derive `options`
+from `onSearch` no longer show a stale, previously-filtered list after the field is
+dismissed without a selection.
+
+**AutocompleteInput:** close the results list when focus leaves the field (e.g. via
+`Tab`), not only on pointer click-outside, so keyboard users don't leave an orphaned
+open listbox.
diff --git a/packages/circuit-ui/components/AutocompleteInput/AutocompleteInput.tsx b/packages/circuit-ui/components/AutocompleteInput/AutocompleteInput.tsx
index 2d36dc2e49..8a56da769f 100644
--- a/packages/circuit-ui/components/AutocompleteInput/AutocompleteInput.tsx
+++ b/packages/circuit-ui/components/AutocompleteInput/AutocompleteInput.tsx
@@ -251,14 +251,16 @@ export const AutocompleteInput = forwardRef<
const syncSearchOnDismiss = useCallback(() => {
if (!Array.isArray(value)) {
- if (searchText !== value?.value) {
+ if (!value && searchText !== '') {
+ changeInputValue(comboboxRef.current, '');
+ } else if (searchText !== value?.value) {
setSearchText(value?.label ?? '');
if (isImmersive) {
setPresentationFieldValue(value?.label ?? '');
}
}
} else if (searchText) {
- setSearchText('');
+ changeInputValue(comboboxRef.current, '');
}
onSearch?.('');
closeResults();