diff --git a/frontend/packages/react-form-wizard/src/inputs/WizArrayInput.tsx b/frontend/packages/react-form-wizard/src/inputs/WizArrayInput.tsx index afb938e1bcb..03f874d10fa 100644 --- a/frontend/packages/react-form-wizard/src/inputs/WizArrayInput.tsx +++ b/frontend/packages/react-form-wizard/src/inputs/WizArrayInput.tsx @@ -21,6 +21,7 @@ import { forwardRef, useCallback, useContext, + useEffect, useLayoutEffect, useMemo, useRef, @@ -77,29 +78,53 @@ export function WizArrayInput(props: WizArrayInputProps) { const onToggle = useCallback(() => setOpen((open: boolean) => !open), []) const path = props.path + const filter = props.filter const { update } = useData() const item = useContext(ItemContext) const values = wizardArrayItems(props, item) + // Tracks the index of the item most recently added via addItem, so it can be + // rendered expanded even when defaultCollapsed collapses pre-existing rows. + const [addedIndex, setAddedIndex] = useState(null) + const addItem = useCallback( (newItem: object | object[]) => { if (path === null) { - ;(item as any[]).push(newItem) + const rawArray = item as any[] + rawArray.push(newItem) + if (filter && !filter(newItem)) { + // The added item won't be rendered at all, so there's no row to expand. + setAddedIndex(null) + } else { + const renderedArray = filter ? rawArray.filter(filter) : rawArray + setAddedIndex(renderedArray.length - 1) + } } else { let newArray = values + let newIndex = newArray.length if (Array.isArray(newItem)) { newArray = [...newArray, ...newItem] + newIndex = newArray.length - newItem.length } else { newArray.push(newItem as never) } setValue(newArray) + setAddedIndex(newIndex) } update() }, - [item, path, setValue, update, values] + [filter, item, path, setValue, update, values] ) + // Clear the added-item marker once it has been used for the initial mount of the + // corresponding ArrayInputItem; later add/remove actions won't re-expand this index. + useEffect(() => { + if (addedIndex !== null) { + setAddedIndex(null) + } + }, [addedIndex]) + if (!values.length && props.disallowEmpty) { addItem(props.newValue ?? {}) } @@ -195,7 +220,7 @@ export function WizArrayInput(props: WizArrayInputProps) { moveUp={moveUp} moveDown={moveDown} removeItem={removeItem} - defaultExpanded={!props.defaultCollapsed} + defaultExpanded={index === addedIndex ? true : !props.defaultCollapsed} hideFromReviewStep={props.hideFromReviewStep} > {props.children}