Refine tag input control

This commit is contained in:
Sam Becker 2026-05-09 16:13:55 -05:00
parent 645110fc36
commit 2f480cfe93
3 changed files with 11 additions and 13 deletions

View File

@ -222,7 +222,6 @@ export default function FieldsetWithStatus({
accessory={tagOptionsAccessory} accessory={tagOptionsAccessory}
onChange={onChange} onChange={onChange}
onInputTextChange={tagOptionsOnInputTextChange} onInputTextChange={tagOptionsOnInputTextChange}
showMenuOnDelete={tagOptionsLimit === 1}
className={clsx(Boolean(error) && 'error')} className={clsx(Boolean(error) && 'error')}
readOnly={readOnly} readOnly={readOnly}
placeholder={placeholder} placeholder={placeholder}

View File

@ -28,7 +28,6 @@ export default function TagInput({
accessory, accessory,
onChange, onChange,
onInputTextChange, onInputTextChange,
showMenuOnDelete,
className, className,
readOnly, readOnly,
placeholder, placeholder,
@ -47,7 +46,6 @@ export default function TagInput({
accessory?: ReactNode accessory?: ReactNode
onChange?: (value: string) => void onChange?: (value: string) => void
onInputTextChange?: (value: string) => void onInputTextChange?: (value: string) => void
showMenuOnDelete?: boolean
className?: string className?: string
readOnly?: boolean readOnly?: boolean
placeholder?: string placeholder?: string
@ -56,7 +54,7 @@ export default function TagInput({
allowNewValues?: boolean allowNewValues?: boolean
shouldParameterize?: boolean shouldParameterize?: boolean
}) { }) {
const behaveAsDropdown = limit === 1; const behavesAsDropdown = limit === 1;
const containerRef = useRef<HTMLInputElement>(null); const containerRef = useRef<HTMLInputElement>(null);
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
@ -77,8 +75,8 @@ export default function TagInput({
const hasReachedLimit = useMemo(() => const hasReachedLimit = useMemo(() =>
limit !== undefined && limit !== undefined &&
selectedOptions.length >= limit && selectedOptions.length >= limit &&
!behaveAsDropdown !behavesAsDropdown
, [limit, behaveAsDropdown, selectedOptions]); , [limit, behavesAsDropdown, selectedOptions]);
const inputTextFormatted = shouldParameterize const inputTextFormatted = shouldParameterize
? parameterize(inputText) ? parameterize(inputText)
@ -150,7 +148,7 @@ export default function TagInput({
.filter(option => !selectedOptions.includes(option)); .filter(option => !selectedOptions.includes(option));
if (optionsToAdd.length > 0) { if (optionsToAdd.length > 0) {
if (behaveAsDropdown) { if (behavesAsDropdown) {
// If behaving as dropdown, replace contents on add // If behaving as dropdown, replace contents on add
onChange?.(optionsToAdd[0]); onChange?.(optionsToAdd[0]);
} else { } else {
@ -165,7 +163,7 @@ export default function TagInput({
setInputText(''); setInputText('');
if ( if (
behaveAsDropdown || behavesAsDropdown ||
(limit !== undefined && limit - 1 >= selectedOptions.length) (limit !== undefined && limit - 1 >= selectedOptions.length)
) { ) {
hideMenu(true); hideMenu(true);
@ -174,7 +172,7 @@ export default function TagInput({
} }
}, [ }, [
limit, limit,
behaveAsDropdown, behavesAsDropdown,
selectedOptions, selectedOptions,
shouldParameterize, shouldParameterize,
onChange, onChange,
@ -192,14 +190,14 @@ export default function TagInput({
// Show options when input text changes // Show options when input text changes
useEffect(() => { useEffect(() => {
if (inputText) { if (inputText) {
if (inputText.includes(',')) { if (inputText.includes(',') && !behavesAsDropdown) {
// eslint-disable-next-line react-hooks/set-state-in-effect // eslint-disable-next-line react-hooks/set-state-in-effect
addOptions(inputText.split(',')); addOptions(inputText.split(','));
} else { } else {
setShouldShowMenu(true); setShouldShowMenu(true);
} }
} }
}, [inputText, addOptions, selectedOptions]); }, [inputText, behavesAsDropdown, addOptions, selectedOptions]);
// Focus option in the DOM when selected index changes // Focus option in the DOM when selected index changes
useEffect(() => { useEffect(() => {
@ -271,7 +269,7 @@ export default function TagInput({
case 'Backspace': case 'Backspace':
if (inputText === '' && selectedOptions.length > 0) { if (inputText === '' && selectedOptions.length > 0) {
removeOption(selectedOptions[selectedOptions.length - 1]); removeOption(selectedOptions[selectedOptions.length - 1]);
if (!showMenuOnDelete) { hideMenu(); } if (!behavesAsDropdown) { hideMenu(); }
} }
break; break;
case 'Escape': case 'Escape':
@ -286,7 +284,7 @@ export default function TagInput({
}, [ }, [
inputText, inputText,
removeOption, removeOption,
showMenuOnDelete, behavesAsDropdown,
hideMenu, hideMenu,
selectedOptions, selectedOptions,
selectedOptionIndex, selectedOptionIndex,

View File

@ -33,6 +33,7 @@ export default function PlaceInput({
if (inputTextDebounced) { if (inputTextDebounced) {
// eslint-disable-next-line react-hooks/set-state-in-effect // eslint-disable-next-line react-hooks/set-state-in-effect
setIsLoadingPlaces(true); setIsLoadingPlaces(true);
console.log('getPlaceAutoCompleteAction', inputTextDebounced);
getPlaceAutoCompleteAction(inputTextDebounced) getPlaceAutoCompleteAction(inputTextDebounced)
.then(options => { .then(options => {
options.forEach(option => { options.forEach(option => {