Skip to content

Instantly share code, notes, and snippets.

@javierllns
Last active June 18, 2024 20:34
Show Gist options
  • Save javierllns/c5135b24e5b32ee6e0a7f3eca6cf7631 to your computer and use it in GitHub Desktop.
Save javierllns/c5135b24e5b32ee6e0a7f3eca6cf7631 to your computer and use it in GitHub Desktop.
A Ultra simplified combobox component based in my other gist called "ShadcnSimplifiedCombobox.tsx".
/*
Author: Javier Antonio Llanos Marriaga
Github: @javierllns
LinkedIn: https://www.linkedin.com/in/javierllns/
Portfolio: https://javierllns.github.io/
-
File name: UltraSimplifiedCombobox.tsx
Description: A Ultra simplified combobox component based in my other gist called "ShadcnSimplifiedCombobox.tsx".
License: MIT
-
Note: If this code has been helpful or inspiration for you, please let me know :).
*/
import { forwardRef } from 'react'
import { cn } from '@components/lib/utils'
import { Button } from '@components/lib/ui/button'
import {
Combobox,
ComboboxRoot,
ComboboxTrigger,
ComboboxContent,
ComboboxItem,
ComboboxOptionsType
} from '@components/lib/ui/custom/combobox'
import { Check, ChevronsUpDown } from 'lucide-react'
export interface SimpleComboboxProps {
value?: string
options: ComboboxOptionsType
placeHolderMessage?: string
searchPlaceHolderMessage?: string
notFoundMessage?: string
onSelect: (value: string) => void
triggerClassName?: string
contentClassName?: string
}
export const SimpleCombobox = forwardRef<HTMLButtonElement, SimpleComboboxProps>(
(
{
value,
options,
placeHolderMessage,
searchPlaceHolderMessage,
notFoundMessage,
onSelect,
triggerClassName,
contentClassName
},
ref
) => {
return (
<div>
<Combobox
value={value}
options={options}
placeHolderMessage={placeHolderMessage}
searchPlaceHolderMessage={searchPlaceHolderMessage}
notFoundMessage={notFoundMessage}
render={(ctx) => {
return (
<ComboboxRoot open={ctx.open} onOpenChange={ctx.setOpen}>
<ComboboxTrigger>
<Button
ref={ref}
className={cn(
'w-[200px] justify-between',
'focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', //? https://github.com/shadcn-ui/ui/discussions/2916
triggerClassName
)}
variant='outline'
role='combobox'
aria-expanded={ctx.open}
>
{ctx.value
? ctx.options.find((opt) => opt.value === ctx.value)?.label
: ctx.placeHolderMessage}
<ChevronsUpDown className='ml-2 h-4 w-4 shrink-0 opacity-50' />
</Button>
</ComboboxTrigger>
<ComboboxContent
className={cn('w-[200px]', contentClassName)}
inputPlaceHolder={ctx.searchPlaceHolderMessage}
notFoundMessage={ctx.notFoundMessage}
>
{ctx.options.map((opt) => (
<ComboboxItem
key={opt.value}
value={opt.value}
onSelect={(currentValue) => {
const newValue = currentValue === ctx.value ? '' : currentValue
onSelect(newValue)
ctx.setOpen(false)
}}
className='p-2'
>
<Check
className={cn(
'mr-2 h-4 w-4',
ctx.value === opt.value ? 'opacity-100' : 'opacity-0'
)}
/>
{opt.label}
</ComboboxItem>
))}
</ComboboxContent>
</ComboboxRoot>
)
}}
/>
</div>
)
}
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment