Commit 17393f5a authored by David Yang's avatar David Yang

Revert "fix: stabilize multi-select autocomplete values"

This reverts commit f1f68f53.
parent 1e3b1c81
import { import {
ChevronDown, ChevronDown,
Check,
Close, Close,
Search, Search,
} from '@/components/AppIcons'; } from '@/components/AppIcons';
...@@ -17,16 +16,6 @@ function defaultFilter(textValue, inputValue) { ...@@ -17,16 +16,6 @@ function defaultFilter(textValue, inputValue) {
return !query || String(textValue || '').toLocaleLowerCase().includes(query); return !query || String(textValue || '').toLocaleLowerCase().includes(query);
} }
function getSelectedKeySet(selectionMode, selectedKey, selectedKeys) {
if (selectionMode === 'multiple') {
return new Set(selectedKeys || []);
}
return new Set(selectedKey === null || selectedKey === undefined ? [] : [selectedKey]);
}
const toSelectionKey = (value) => String(value ?? '');
export default function XinyuanAutocomplete({ export default function XinyuanAutocomplete({
'aria-label': ariaLabel, 'aria-label': ariaLabel,
className, className,
...@@ -43,73 +32,21 @@ export default function XinyuanAutocomplete({ ...@@ -43,73 +32,21 @@ export default function XinyuanAutocomplete({
renderOption, renderOption,
searchPlaceholder = '输入关键词搜索', searchPlaceholder = '输入关键词搜索',
selectedKey, selectedKey,
selectedKeys,
selectionMode = 'single',
shouldFilter = true, shouldFilter = true,
valueText, valueText,
variant = 'secondary', variant = 'secondary',
}) { }) {
const selectedKeySet = getSelectedKeySet( const selectedOption = options.find((option) => option.id === selectedKey);
selectionMode, const resolvedValue = valueText ?? selectedOption?.label ?? placeholder;
selectedKey,
selectedKeys,
);
const selectedKeyStringSet = new Set(
Array.from(selectedKeySet).map(toSelectionKey),
);
const selectedOptions = options.filter((option) =>
selectedKeyStringSet.has(toSelectionKey(option.id)),
);
const resolvedValue =
valueText ??
(selectedOptions.length > 0
? selectedOptions.map((option) => option.label).join('、')
: placeholder);
const rootSelectionProps =
selectionMode === 'multiple'
? { selectedKeys: selectedKeyStringSet }
: { selectedKey };
const listBoxSelectionProps =
selectionMode === 'multiple'
? {
selectionMode,
selectedKeys: selectedKeyStringSet,
}
: {};
const visibleOptions = isLoading || errorText ? [] : options; const visibleOptions = isLoading || errorText ? [] : options;
const handleMultipleOptionPress = (option) => {
if (
selectionMode !== 'multiple' ||
!onSelectionChange ||
option?.isDisabled
) {
return;
}
const optionKey = toSelectionKey(option.id);
if (!optionKey) {
return;
}
const nextKeys = new Set(
Array.from(selectedKeyStringSet).filter(Boolean),
);
if (nextKeys.has(optionKey)) {
nextKeys.delete(optionKey);
} else {
nextKeys.add(optionKey);
}
onSelectionChange(nextKeys);
};
return ( return (
<Autocomplete <Autocomplete
{...rootSelectionProps}
aria-label={ariaLabel || placeholder} aria-label={ariaLabel || placeholder}
className={className} className={className}
fullWidth fullWidth
isDisabled={isDisabled} isDisabled={isDisabled}
selectionMode={selectionMode} selectedKey={selectedKey}
variant={variant} variant={variant}
onSelectionChange={onSelectionChange} onSelectionChange={onSelectionChange}
> >
...@@ -138,41 +75,19 @@ export default function XinyuanAutocomplete({ ...@@ -138,41 +75,19 @@ export default function XinyuanAutocomplete({
</SearchField> </SearchField>
<ListBox <ListBox
aria-label={ariaLabel || placeholder} aria-label={ariaLabel || placeholder}
dependencies={[Array.from(selectedKeyStringSet).sort().join('\u0000')]}
items={visibleOptions} items={visibleOptions}
{...listBoxSelectionProps}
renderEmptyState={() => ( renderEmptyState={() => (
<div className="grid min-h-20 place-items-center px-3 py-4"> <div className="grid min-h-20 place-items-center px-3 py-4">
{isLoading ? <Spinner size="sm" /> : errorText || emptyText} {isLoading ? <Spinner size="sm" /> : errorText || emptyText}
</div> </div>
)} )}
> >
{(option) => { {(option) => (
const isSelected = selectedKeyStringSet.has(toSelectionKey(option.id)); <ListBox.Item id={option.id} textValue={option.textValue || option.label}>
return (
<ListBox.Item
id={option.id}
isDisabled={option.isDisabled}
textValue={option.textValue || option.label}
{...(selectionMode === 'multiple'
? { onPress: () => handleMultipleOptionPress(option) }
: {})}
>
{renderOption ? renderOption(option) : <Label>{option.label}</Label>} {renderOption ? renderOption(option) : <Label>{option.label}</Label>}
{selectionMode === 'multiple' ? (
<span
aria-hidden="true"
className="ml-auto inline-flex w-5 justify-center text-foreground"
>
{isSelected ? <Check size={14} /> : null}
</span>
) : (
<ListBox.ItemIndicator /> <ListBox.ItemIndicator />
)}
</ListBox.Item> </ListBox.Item>
); )}
}}
</ListBox> </ListBox>
</Autocomplete.Filter> </Autocomplete.Filter>
</Autocomplete.Popover> </Autocomplete.Popover>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment