feat(checkout): fix searchable select API search and add billing destination
Fixes: 1. SearchableSelect now supports onSearch prop for API-based search - Added onSearch and isSearching props - shouldFilter disabled when onSearch provided 2. DynamicCheckoutField connects handleApiSearch to SearchableSelect 3. RAJAONGKIR_INTEGRATION.md adds both billing and shipping destination_id This enables the destination search field to actually call the API when user types, instead of just filtering local (empty) options.
This commit is contained in:
@@ -162,7 +162,9 @@ export function DynamicCheckoutField({
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
}}
|
||||
placeholder={isSearching ? 'Searching...' : (field.placeholder || `Search ${field.label}...`)}
|
||||
onSearch={handleApiSearch}
|
||||
isSearching={isSearching}
|
||||
placeholder={field.placeholder || `Search ${field.label}...`}
|
||||
emptyLabel={
|
||||
isSearching
|
||||
? 'Searching...'
|
||||
|
||||
@@ -28,6 +28,9 @@ interface Props {
|
||||
emptyLabel?: string;
|
||||
className?: string;
|
||||
disabled?: boolean;
|
||||
// For API-based search
|
||||
onSearch?: (searchTerm: string) => void;
|
||||
isSearching?: boolean;
|
||||
}
|
||||
|
||||
export function SearchableSelect({
|
||||
@@ -38,12 +41,26 @@ export function SearchableSelect({
|
||||
emptyLabel = "No results found.",
|
||||
className,
|
||||
disabled = false,
|
||||
onSearch,
|
||||
isSearching = false,
|
||||
}: Props) {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const [searchValue, setSearchValue] = React.useState("");
|
||||
const selected = options.find((o) => o.value === value);
|
||||
|
||||
React.useEffect(() => { if (disabled && open) setOpen(false); }, [disabled, open]);
|
||||
|
||||
// Handle search input changes
|
||||
const handleSearchChange = (value: string) => {
|
||||
setSearchValue(value);
|
||||
if (onSearch) {
|
||||
onSearch(value);
|
||||
}
|
||||
};
|
||||
|
||||
// Determine if we should use local filtering or API-based search
|
||||
const shouldFilter = !onSearch;
|
||||
|
||||
return (
|
||||
<Popover open={disabled ? false : open} onOpenChange={(o) => !disabled && setOpen(o)}>
|
||||
<PopoverTrigger asChild>
|
||||
@@ -69,10 +86,16 @@ export function SearchableSelect({
|
||||
align="start"
|
||||
sideOffset={4}
|
||||
>
|
||||
<Command shouldFilter>
|
||||
<CommandInput placeholder="Search..." />
|
||||
<Command shouldFilter={shouldFilter}>
|
||||
<CommandInput
|
||||
placeholder="Search..."
|
||||
value={searchValue}
|
||||
onValueChange={handleSearchChange}
|
||||
/>
|
||||
<CommandList>
|
||||
<CommandEmpty>{emptyLabel}</CommandEmpty>
|
||||
<CommandEmpty>
|
||||
{isSearching ? "Searching..." : emptyLabel}
|
||||
</CommandEmpty>
|
||||
{options.map((opt) => (
|
||||
<CommandItem
|
||||
key={opt.value}
|
||||
@@ -80,6 +103,7 @@ export function SearchableSelect({
|
||||
onSelect={() => {
|
||||
onChange?.(opt.value);
|
||||
setOpen(false);
|
||||
setSearchValue("");
|
||||
}}
|
||||
>
|
||||
<Check
|
||||
|
||||
Reference in New Issue
Block a user