Skip to content

Commit

Permalink
fix: BaseInput 2 clicks on dropdown
Browse files Browse the repository at this point in the history
  • Loading branch information
saurabhdaware committed Feb 5, 2024
1 parent e98c336 commit 7f6bc56
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 17 deletions.
40 changes: 24 additions & 16 deletions packages/blade/src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { isReactNative } from '~utils';
import { MetaConstants, metaAttribute } from '~utils/metaAttribute';
import { throwBladeError } from '~utils/logger';
import type { ContainerElementType } from '~utils/types';
import { useControllableState } from '~utils/useControllable';

const validDropdownChildren = [
dropdownComponentIds.triggers.SelectInput,
Expand Down Expand Up @@ -58,7 +59,6 @@ const _Dropdown = ({
testID,
...styledProps
}: DropdownProps): React.ReactElement => {
const [isOpen, setIsOpen] = React.useState<boolean>(isOpenControlled ?? false);
const [options, setOptions] = React.useState<DropdownContextType['options']>([]);
const [filteredValues, setFilteredValues] = React.useState<string[]>([]);
const [selectedIndices, setSelectedIndices] = React.useState<
Expand Down Expand Up @@ -97,19 +97,27 @@ const _Dropdown = ({

const dropdownBaseId = useId('dropdown');

const setIsOpenControlled = (isControlledStateOpen: boolean): void => {
onOpenChange?.(isControlledStateOpen);
const [isDropdownOpen, setIsDropdownOpen] = useControllableState({
value: isOpenControlled,
defaultValue: false,
onChange: (isOpenControlledValue) => {
isDropdownOpenRef.current = isOpenControlledValue;

Check failure on line 104 in packages/blade/src/components/Dropdown/Dropdown.tsx

View workflow job for this annotation

GitHub Actions / Validate Source Code

'isDropdownOpenRef' was used before it was defined
onOpenChange?.(isOpenControlledValue);
},
});

const isDropdownOpenRef = React.useRef(isDropdownOpen);

const setIsOpen = (isOpenValue: boolean): void => {
isDropdownOpenRef.current = isOpenValue;
setIsDropdownOpen(() => isOpenValue);
};

const close = React.useCallback(() => {
setActiveTagIndex(-1);
if (isOpenControlled === undefined) {
setIsOpen(false);
} else {
setIsOpenControlled(false);
}
setIsOpen(false);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isOpenControlled]);
}, []);

React.Children.map(children, (child) => {
if (React.isValidElement(child)) {
Expand Down Expand Up @@ -140,8 +148,8 @@ const _Dropdown = ({

const contextValue = React.useMemo<DropdownContextType>(
() => ({
isOpen: isOpenControlled === undefined ? isOpen : isOpenControlled,
setIsOpen: isOpenControlled === undefined ? setIsOpen : setIsOpenControlled,
isOpen: isDropdownOpen,
setIsOpen,
close,
selectedIndices,
setSelectedIndices,
Expand Down Expand Up @@ -178,7 +186,7 @@ const _Dropdown = ({
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[
isOpen,
isDropdownOpen,
isOpenControlled,
selectedIndices,
controlledValueIndices,
Expand All @@ -197,15 +205,15 @@ const _Dropdown = ({

const BottomSheetAndDropdownGlueContextValue = React.useMemo((): BottomSheetAndDropdownGlueContext => {
return {
isOpen,
isOpen: isDropdownOpen,
dropdownHasBottomSheet,
hasAutoCompleteInBottomSheetHeader,
setDropdownHasBottomSheet,
// This is the dismiss function which will be injected into the BottomSheet
// Basically <BottomSheet onDismiss={onBottomSheetDismiss} />
onBottomSheetDismiss: close,
};
}, [dropdownHasBottomSheet, hasAutoCompleteInBottomSheetHeader, isOpen, close]);
}, [dropdownHasBottomSheet, hasAutoCompleteInBottomSheetHeader, isDropdownOpen, close]);

React.useEffect((): (() => void) | undefined => {
if (!isReactNative()) {
Expand All @@ -219,9 +227,9 @@ const _Dropdown = ({
}

const isOutsideClick = !dropdown.contains(target) && !isTagDismissedRef.current?.value;
const dropdownIsOpen = typeof isOpenControlled === 'undefined' ? isOpen : isOpenControlled;

if (isOutsideClick && dropdownIsOpen) {
const isDropdownOpenState = isDropdownOpenRef.current;
if (isOutsideClick && isDropdownOpenState) {
close();
}

Expand Down
3 changes: 2 additions & 1 deletion packages/blade/src/components/Input/BaseInput/BaseInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -908,7 +908,8 @@ const _BaseInput: React.ForwardRefRenderFunction<BladeElementRef, BaseInputProps
handleOnSubmit={handleOnSubmit}
handleOnInput={handleOnInput}
handleOnKeyDown={handleOnKeyDown}
handleOnClick={handleOnClick}
// In DropdownTrigger, click is handled on BaseInputTagSlot to cover padding around the real input
handleOnClick={isDropdownTrigger ? undefined : handleOnClick}
leadingIcon={leadingIcon}
prefix={prefix}
interactionElement={interactionElement}
Expand Down

0 comments on commit 7f6bc56

Please sign in to comment.