Skip to content

Commit

Permalink
use state to check if the user has interacted with the repeatableField
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnC-80 committed Oct 28, 2024
1 parent 21e9222 commit e93e0cd
Showing 1 changed file with 11 additions and 11 deletions.
22 changes: 11 additions & 11 deletions lib/RepeatableField/RepeatableField.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useRef, useEffect } from 'react';
import React, { useRef, useEffect, useState } from 'react';
import classnames from 'classnames';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
Expand All @@ -10,8 +10,6 @@ import EmptyMessage from '../EmptyMessage';
import IconButton from '../IconButton';
import { RepeatableFieldContent } from './RepeatableFieldContent';
import css from './RepeatableField.css';
import { useFocusedIndex } from './hooks/useFocusedIndex';
import { useIsElementFocused } from './hooks/useIsElementFocused';
import { getFirstFocusable } from '../../util/getFocusableElements';

const RepeatableField = ({
Expand All @@ -33,8 +31,7 @@ const RepeatableField = ({
const rootRef = useRef(null);
const showDeleteBtn = typeof onRemove === 'function';
const fieldsLength = fields.length;
const isSomeChildElementFocused = useIsElementFocused(rootRef);
const focusedIndex = useFocusedIndex(fieldsLength);
const [hasBeenFocused, setHasBeenFocused] = useState(false);

// use mutation observers to handle focus-management since we only have internal state.
useEffect(() => {
Expand All @@ -46,8 +43,12 @@ const RepeatableField = ({
const removedNode = mutation.removedNodes?.[0];
let rowElem;
// Handle added node
if (rootRef.current.matches(':focus-within')) {
if (addedNode && addedNode.matches(`.${css.repeatableFieldItem}`)) {
// we check if the user has interacted with the component before handling this, otherwise focus could be
// unwantedly moved when a form is initialized.
if (hasBeenFocused) {
if (addedNode &&
addedNode.nodeType === 1 &&
addedNode.matches(`.${css.repeatableFieldItem}`)) {
rowElem = getFirstFocusable(addedNode);
rowElem?.focus();
}
Expand All @@ -74,16 +75,16 @@ const RepeatableField = ({
return () => {
observer.disconnect();
};
}, [])

const hasToBeFocused = (index) => isSomeChildElementFocused && focusedIndex === index;
}, [hasBeenFocused])

return (
<fieldset
ref={rootRef}
id={id}
data-test-repeatable-field
className={classnames(css.repeatableField, { [css.hasMargin]: hasMargin }, className)}
tabIndex="-1"
onFocus={() => { setHasBeenFocused(true) }}
>
{legend && (
<Headline
Expand Down Expand Up @@ -126,7 +127,6 @@ const RepeatableField = ({
>
<RepeatableFieldContent
rootRef={rootRef}
isFocused={hasToBeFocused(index)}
>
{renderField(field, index, fields)}
</RepeatableFieldContent>
Expand Down

0 comments on commit e93e0cd

Please sign in to comment.