[ui][typeahead] add isLoading prop

pull/519/head
Yangshun Tay 2 years ago
parent c0e9b6c138
commit be52ecc51b

@ -3,7 +3,9 @@ import type { InputHTMLAttributes } from 'react';
import { useId } from 'react'; import { useId } from 'react';
import { Fragment, useState } from 'react'; import { Fragment, useState } from 'react';
import { Combobox, Transition } from '@headlessui/react'; import { Combobox, Transition } from '@headlessui/react';
import { ChevronDownIcon } from '@heroicons/react/20/solid'; import { CheckIcon, ChevronDownIcon } from '@heroicons/react/20/solid';
import { Spinner } from '..';
export type TypeaheadOption = Readonly<{ export type TypeaheadOption = Readonly<{
// String value to uniquely identify the option. // String value to uniquely identify the option.
@ -27,6 +29,7 @@ type Attributes = Pick<
type Props = Readonly<{ type Props = Readonly<{
errorMessage?: React.ReactNode; errorMessage?: React.ReactNode;
isLabelHidden?: boolean; isLabelHidden?: boolean;
isLoading?: boolean;
label: string; label: string;
// Minimum query length before any results will be shown. // Minimum query length before any results will be shown.
minQueryLength?: number; minQueryLength?: number;
@ -81,6 +84,7 @@ export default function Typeahead({
disabled = false, disabled = false,
errorMessage, errorMessage,
isLabelHidden, isLabelHidden,
isLoading = false,
label, label,
minQueryLength = 0, minQueryLength = 0,
noResultsMessage = 'No results', noResultsMessage = 'No results',
@ -163,14 +167,20 @@ export default function Typeahead({
}} }}
{...props} {...props}
/> />
{isLoading ? (
<div className="absolute inset-y-0 right-0 flex items-center pr-2">
<Spinner size="xs" />
</div>
) : (
<Combobox.Button className="absolute inset-y-0 right-0 flex items-center pr-2"> <Combobox.Button className="absolute inset-y-0 right-0 flex items-center pr-2">
<ChevronDownIcon <ChevronDownIcon
aria-hidden="true" aria-hidden="true"
className="h-5 w-5 text-slate-400" className="h-5 w-5 text-slate-400"
/> />
</Combobox.Button> </Combobox.Button>
)}
</div> </div>
{query.length >= minQueryLength && ( {query.length >= minQueryLength && !isLoading && (
<Transition <Transition
afterLeave={() => setQuery('')} afterLeave={() => setQuery('')}
as={Fragment} as={Fragment}
@ -198,13 +208,26 @@ export default function Typeahead({
} }
value={option}> value={option}>
{({ selected }) => ( {({ selected }) => (
<>
<span <span
className={clsx( className={clsx(
'block truncate', 'block truncate',
selected ? 'font-medium' : 'font-normal', selected && 'font-medium',
)}> )}>
{option.label} {option.label}
</span> </span>
{selected && (
<span
className={clsx(
'absolute inset-y-0 right-0 flex items-center pr-4',
)}>
<CheckIcon
aria-hidden="true"
className="h-5 w-5"
/>
</span>
)}
</>
)} )}
</Combobox.Option> </Combobox.Option>
)) ))

Loading…
Cancel
Save