-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: ComboBox show all items on open #2328
Changes from all commits
5269b19
2b3905b
92af58b
56ee44c
f460a62
d3ae40c
733a315
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
import { | ||
ComboBoxNormalized, | ||
type MenuTriggerAction, | ||
type NormalizedItem, | ||
type SpectrumComboBoxProps, | ||
} from '@deephaven/components'; | ||
import { useCallback } from 'react'; | ||
import { useCallback, useRef } from 'react'; | ||
import { type PickerWithTableProps } from './PickerProps'; | ||
import { usePickerProps } from './utils'; | ||
|
||
|
@@ -18,19 +19,57 @@ export function ComboBox(props: ComboBoxProps): JSX.Element { | |
...pickerProps | ||
} = usePickerProps<ComboBoxProps>(props); | ||
|
||
const isOpenRef = useRef(false); | ||
const inputValueRef = useRef(''); | ||
|
||
const onInputChange = useCallback( | ||
(value: string) => { | ||
onInputChangeInternal?.(value); | ||
onSearchTextChange(value); | ||
|
||
// Only apply search text if ComboBox is open. | ||
if (isOpenRef.current) { | ||
onSearchTextChange(value); | ||
} | ||
// When the ComboBox is closed, `onInputChange` may have been called as a | ||
// result of user search input, ComboBox selection, or by selected key | ||
// prop changes. We can't determine the source here, so we clear the search | ||
// text and store the search value so that the list is unfiltered the next | ||
// time the ComboBox is opened. We also store the search value so we can | ||
// re-apply it in `onOpenChange` if the ComboBox is opened by user search | ||
// input. | ||
else { | ||
onSearchTextChange(''); | ||
inputValueRef.current = value; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this be set in all cases? Everything else looks good. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm on the fence on this one. My reasoning for only putting it here was that the only consumer should be the |
||
} | ||
}, | ||
[onInputChangeInternal, onSearchTextChange] | ||
); | ||
|
||
const onOpenChange = useCallback( | ||
(isOpen: boolean, menuTrigger?: MenuTriggerAction) => { | ||
pickerProps.onOpenChange?.(isOpen); | ||
|
||
// Reset the search text when the ComboBox is closed. | ||
if (!isOpen) { | ||
onSearchTextChange(''); | ||
} | ||
// Restore search text when ComboBox has been opened by user input. | ||
else if (menuTrigger === 'input') { | ||
onSearchTextChange(inputValueRef.current); | ||
} | ||
|
||
// Store the open state so that `onInputChange` has access to it. | ||
isOpenRef.current = isOpen; | ||
}, | ||
[onSearchTextChange, pickerProps] | ||
); | ||
|
||
return ( | ||
<ComboBoxNormalized | ||
// eslint-disable-next-line react/jsx-props-no-spreading | ||
{...pickerProps} | ||
onInputChange={onInputChange} | ||
onOpenChange={onOpenChange} | ||
/> | ||
); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside - not our naming, but I was worried this name would conflict with something from the
@react-types/menu
package. But there they haveMenuTriggerType
.I don't know why they didn't call this
ComboBoxTriggerType
or something instead, but whatever.