Skip to content
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

feat(autocomplete): Possible solution for object-checking #3455

Merged
merged 1 commit into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -243,15 +243,25 @@ export const OptionComponent: StoryFn<AutocompleteProps<MyOptionType>> = (
options={options}
optionLabel={(opt) => `${opt.trend} ${opt.label} (${opt.symbol})`}
optionComponent={CustomItem}
initialSelectedOptions={[options[1]]}
initialSelectedOptions={
[JSON.parse(JSON.stringify(options[1]))] as MyOptionType[]
}
itemCompare={(item, compare) => {
return item.label === compare.label
}}
multiline
/>
<Autocomplete
label="Select multiple stocks"
options={options}
optionLabel={(opt) => `${opt.trend} ${opt.label} (${opt.symbol})`}
optionComponent={CustomItem}
initialSelectedOptions={[options[1]]}
initialSelectedOptions={
JSON.parse(JSON.stringify([options[1], options[2]])) as MyOptionType[]
}
itemCompare={(item, compare) => {
return item.label === compare.label
}}
multiline
multiple
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ const handleListFocus = (e: FocusEvent<HTMLElement>) => {

const defaultOptionDisabled = () => false

type OptionLabelProps<T> = T extends string | number
// prettier-ignore
type OptionLabelProps<T,> = T extends string | number
? {
/** Custom option label */
optionLabel?: (option: T) => string
Expand Down Expand Up @@ -325,6 +326,10 @@ export type AutocompleteProps<T> = {
* @default 300
*/
dropdownHeight?: number
/**
* Method that is used to compare objects by value. If omitted, objects are matched by reference.
*/
itemCompare?: (value: T, compare: T) => boolean
} & HTMLAttributes<HTMLDivElement> &
OptionLabelProps<T>

Expand All @@ -344,10 +349,11 @@ function AutocompleteInner<T>(
hideClearButton = false,
onOptionsChange,
onInputChange,
selectedOptions,
selectedOptions: _selectedOptions,
multiple,
itemCompare,
allowSelectAll,
initialSelectedOptions = [],
initialSelectedOptions: _initialSelectedOptions = [],
disablePortal,
optionDisabled = defaultOptionDisabled,
optionsFilter,
Expand All @@ -365,6 +371,21 @@ function AutocompleteInner<T>(
...other
} = props

const selectedOptions = _selectedOptions
? itemCompare
? options.filter((item) =>
_selectedOptions.some((compare) => itemCompare(item, compare)),
)
: _selectedOptions
: undefined
const initialSelectedOptions = _initialSelectedOptions
? itemCompare
? options.filter((item) =>
_initialSelectedOptions.some((compare) => itemCompare(item, compare)),
)
: _initialSelectedOptions
: undefined

if (disablePortal) {
console.warn(
'Autocomplete "disablePortal" prop has been deprecated. Autocomplete now uses the native popover api',
Expand Down Expand Up @@ -423,9 +444,14 @@ function AutocompleteInner<T>(
...multipleSelectionProps,
onSelectedItemsChange: (changes) => {
if (onOptionsChange) {
const selectedItems = changes.selectedItems.filter(
let selectedItems = changes.selectedItems.filter(
(item) => item !== AllSymbol,
)
if (itemCompare) {
selectedItems = inputOptions.filter((item) =>
selectedItems.some((compare) => itemCompare(item, compare)),
)
}
onOptionsChange({ selectedItems })
}
},
Expand Down Expand Up @@ -607,7 +633,12 @@ function AutocompleteInner<T>(
...comboBoxProps,
onSelectedItemChange: (changes) => {
if (onOptionsChange) {
const { selectedItem } = changes
let { selectedItem } = changes
if (itemCompare) {
selectedItem = inputOptions.find((item) =>
itemCompare(item, selectedItem),
)
}
onOptionsChange({
selectedItems: selectedItem ? [selectedItem] : [],
})
Expand Down
Loading