diff --git a/sample/index.tsx b/sample/index.tsx index 4772dc8..c7e42fb 100644 --- a/sample/index.tsx +++ b/sample/index.tsx @@ -184,6 +184,7 @@ const Application = () => { onValueChange={setVirtualSelectOption} options={getLargeSelectOptions()} className='w-60' + enableClear /> diff --git a/src/VirtualSelect/index.tsx b/src/VirtualSelect/index.tsx index f0bddaf..a214d00 100644 --- a/src/VirtualSelect/index.tsx +++ b/src/VirtualSelect/index.tsx @@ -3,10 +3,10 @@ import { Combobox } from '@headlessui/react'; import { tremorTwMerge } from '@tremor/react/dist/lib/tremorTwMerge'; import { ReactSelectOption } from '../Select'; import { spacing } from '@tremor/react/dist/lib/spacing'; -import { sizing } from '@tremor/react/dist/lib/sizing'; import { border } from '@tremor/react/dist/lib/shape'; import { makeClassName } from '@tremor/react/dist/lib/utils'; import { getSelectButtonColors, hasValue } from '@tremor/react/dist/components/input-elements/selectUtils'; +import { ChevronDown16Filled, DismissCircle16Filled } from '@fluentui/react-icons'; export interface SearchSelectProps extends React.HTMLAttributes { defaultValue?: string; @@ -14,8 +14,8 @@ export interface SearchSelectProps extends React.HTMLAttributes onValueChange: (value: string) => void; placeholder?: string; disabled?: boolean; - icon?: React.ElementType | React.JSXElementConstructor; options: ReactSelectOption[]; + enableClear?: boolean; } export interface IconSettings extends React.HTMLAttributes { @@ -44,8 +44,8 @@ export const comboBoxStyles = (value: T, disabled: boolean, icon: boolean) = 'w-full outline-none text-left whitespace-nowrap truncate rounded-tremor-default focus:ring-2 transition duration-100 text-tremor-default', 'border-tremor-border shadow-tremor-input focus:border-tremor-brand-subtle focus:ring-tremor-brand-muted', 'dark:border-dark-tremor-border dark:shadow-dark-tremor-input dark:focus:border-dark-tremor-brand-subtle dark:focus:ring-dark-tremor-brand-muted', - icon ? 'p-10 -ml-0.5' : spacing.lg.paddingLeft, - spacing.fourXl.paddingRight, + spacing.lg.paddingLeft, + icon ? 'pl-3 pr-12' : spacing.fourXl.paddingRight, spacing.sm.paddingY, border.sm.all, disabled @@ -72,71 +72,55 @@ export const comboBoxSingleOptionStyles = (className: string | undefined) => spacing.md.paddingX, spacing.md.paddingY, className, + 'my-0', ); -export const IconSearch = ({ icon }: IconSettings) => { - const Icon = icon; - - return ( - - - - ); -}; - -const ArrowDownHeadIcon = ({ ...props }) => ( - - - -); - export const ArrowDownHead = () => (
-
); +const SelectClearButton = ({ clearValue }: { clearValue: (e: string) => void }) => ( + +); + export const VirtualSelect = React.forwardRef(function SearchSelect(props, ref) { const { value, onValueChange, placeholder = 'Select...', disabled = false, - icon, className, + enableClear, options, ...other } = props; const [searchQuery, setSearchQuery] = useState(''); - const valueToNameMapping = useMemo(() => constructValueToNameMapping(options), [options]); const filteredOptions = useMemo(() => getFilteredOptions(searchQuery, options), [searchQuery, options]); + const valueToNameMapping = useMemo(() => constructValueToNameMapping(filteredOptions), [filteredOptions]); + + const onOptionClick = (option: string) => () => { + setSearchQuery(''); + onValueChange(option); + }; return ( as='div' ref={ref} value={value} - onChange={onValueChange} disabled={disabled} + nullable + onChange={() => setSearchQuery('')} className={tremorTwMerge('w-full min-w-[10rem] relative text-tremor-default', className)} > - {icon && } setSearchQuery(event.target.value)} - displayValue={(selected: string) => valueToNameMapping.get(selected) ?? ''} + displayValue={() => searchQuery || valueToNameMapping.get(value ?? '') || ''} /> + {enableClear && value ? : null} - + {({ option }) => ( - + {valueToNameMapping.get(option as string)} )}