Skip to content

Commit

Permalink
Merge pull request #207 from jetstreamapp/bug/205
Browse files Browse the repository at this point in the history
Virtual scroll bugfixes
  • Loading branch information
paustint authored Mar 13, 2023
2 parents 8230052 + cca406e commit 15981ec
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 12 deletions.
21 changes: 13 additions & 8 deletions libs/ui/src/lib/form/combobox/Combobox.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { SerializedStyles } from '@emotion/react';
import { logger } from '@jetstream/shared/client-logger';
import {
isAlphaNumericKey,
isArrowDownKey,
isArrowUpKey,
isEnterKey,
Expand Down Expand Up @@ -88,6 +89,7 @@ function getContainer(hasGroup: boolean, children: React.ReactNode) {
if (hasGroup) {
return <div className="slds-combobox-group">{children}</div>;
}
// eslint-disable-next-line react/jsx-no-useless-fragment
return <Fragment>{children}</Fragment>;
}

Expand All @@ -112,13 +114,6 @@ const iconNotLoading = (
/>
);

/**
* Optimization to skip re-renders of parts of component
*/
// export const Combobox = forwardRef((props: ComboboxProps, ref) => (
// <ComboboxElement ref={ref} {...props} icon={props.loading ? iconLoading : iconNotLoading} />
// ));

export const Combobox = forwardRef<ComboboxPropsRef, ComboboxProps>(
(
{
Expand Down Expand Up @@ -152,6 +147,8 @@ export const Combobox = forwardRef<ComboboxPropsRef, ComboboxProps>(
}: ComboboxProps,
ref
) => {
// store keys user typed in so that if typing triggered open, we can ensure input is set to this value
const inputBuffer = useRef('');
const popoverRef = useRef<HTMLDivElement | null>(null);
const [isOpen, setIsOpen] = useState<boolean>(false);
const [id] = useState<string>(uniqueId('Combobox'));
Expand Down Expand Up @@ -208,8 +205,9 @@ export const Combobox = forwardRef<ComboboxPropsRef, ComboboxProps>(
// when closed, set input value in case user modified
useEffect(() => {
if (isOpen) {
setValue('');
setValue(inputBuffer.current || '');
} else {
inputBuffer.current = '';
setFocusedItem(null);
if (value !== (selectedItemLabel || '')) {
setValue(selectedItemLabel || '');
Expand Down Expand Up @@ -348,9 +346,16 @@ export const Combobox = forwardRef<ComboboxPropsRef, ComboboxProps>(
} else {
setFocusedItem(0);
}
} else if (isEscapeKey(event)) {
setIsOpen(false);
} else if (isEnterKey(event) && isOpen && onInputEnter) {
onInputEnter();
} else {
if (isAlphaNumericKey(event) && !isOpen) {
// save input so that when we open, we can set the value instead of clearing it
inputBuffer.current = `${inputBuffer.current}${event.currentTarget.value}`;
setIsOpen(true);
}
onInputChange && onInputChange(event.currentTarget.value);
onFilterInputChange && onFilterInputChange(event.currentTarget.value);
}
Expand Down
21 changes: 17 additions & 4 deletions libs/ui/src/lib/form/combobox/ComboboxWithItemsVirtual.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,19 @@ export const ComboboxWithItemsVirtual: FunctionComponent<ComboboxWithItemsVirtua
},
});

const handleSelection = useCallback(
(value: ListItem) => {
onSelected(value);
setFocusedIndex(null);
},
[onSelected]
);

// ensure that focused item is removed if user types something
useEffect(() => {
setFocusedIndex(null);
}, [filterTextNonDebounced]);

useEffect(() => {
if (selectedItemId) {
setSelectedItem(items.find((item) => item.id === selectedItemId));
Expand Down Expand Up @@ -136,7 +149,7 @@ export const ComboboxWithItemsVirtual: FunctionComponent<ComboboxWithItemsVirtua
tempFocusedIndex = null;
setFocusedIndex(tempFocusedIndex);
}
isNumber(focusedIndex) && onSelected(visibleItems[focusedIndex]);
isNumber(focusedIndex) && handleSelection(visibleItems[focusedIndex]);
return;
}
default:
Expand Down Expand Up @@ -175,9 +188,9 @@ export const ComboboxWithItemsVirtual: FunctionComponent<ComboboxWithItemsVirtua
const onInputEnter = useCallback(() => {
const firstItem = visibleItems.find((item) => !item.isGroup);
if (firstItem) {
onSelected(firstItem);
handleSelection(firstItem);
}
}, [onSelected, visibleItems]);
}, [handleSelection, visibleItems]);

const virtualItems = rowVirtualizer.getVirtualItems();

Expand Down Expand Up @@ -248,7 +261,7 @@ export const ComboboxWithItemsVirtual: FunctionComponent<ComboboxWithItemsVirtua
selected={item.id === selectedItem?.id}
focused={virtualItem.index === focusedIndex}
onSelection={() => {
onSelected(item);
handleSelection(item);
}}
/>
);
Expand Down

0 comments on commit 15981ec

Please sign in to comment.