Skip to content

Instantly share code, notes, and snippets.

@javierllns
Last active June 18, 2024 20:33
Show Gist options
  • Save javierllns/02fb256052bbe01a585f7da9324766e4 to your computer and use it in GitHub Desktop.
Save javierllns/02fb256052bbe01a585f7da9324766e4 to your computer and use it in GitHub Desktop.
A "simplified" "form-like-style" "stylable" version of Shadcn UI combobox examples.
/*
Author: Javier Antonio Llanos Marriaga
Github: @javierllns
LinkedIn: https://www.linkedin.com/in/javierllns/
Portfolio: https://javierllns.github.io/
-
File name: ShadcnSimplifiedCombobox.tsx
Description: A "simplified" "form-like-style" "stylable" version of Shadcn UI combobox examples.
License: MIT
-
Note: If this code has been helpful or inspiration for you, please let me know :).
*/
import { useState, ReactNode } from 'react'
import { cn } from '@components/lib/utils'
import { Popover, PopoverContent, PopoverTrigger } from '@components/lib/ui/popover'
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList
} from '@components/lib/ui/command'
export interface ComboboxOptionType {
label: string
value: string
}
export type ComboboxOptionsType = Array<ComboboxOptionType>
function ComboboxRoot({
children,
open,
onOpenChange
}: {
children: ReactNode
open: boolean
onOpenChange: React.Dispatch<React.SetStateAction<boolean>>
}): JSX.Element {
return (
<Popover open={open} onOpenChange={onOpenChange}>
{children}
</Popover>
)
}
function ComboboxTrigger({ children }: { children: ReactNode }): JSX.Element {
return <PopoverTrigger asChild>{children}</PopoverTrigger>
}
function ComboboxContent({
children,
inputPlaceHolder = 'Search option...',
notFoundMessage = 'No option found.',
className = ''
}: {
children?: ReactNode
inputPlaceHolder?: string
notFoundMessage?: string
className?: string
}): JSX.Element {
return (
<PopoverContent className={cn('w-[200px] p-0', className)}>
<Command>
<CommandInput placeholder={inputPlaceHolder} />
<CommandList>
<CommandEmpty>{notFoundMessage}</CommandEmpty>
<CommandGroup>{children}</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
)
}
function Combobox({
value = '',
options = [],
placeHolderMessage = 'Select option...',
searchPlaceHolderMessage = 'Search option...',
notFoundMessage = 'No option found.',
render
}: {
value?: string
options: ComboboxOptionsType
placeHolderMessage?: string
searchPlaceHolderMessage?: string
notFoundMessage?: string
render: (ctx: {
value: string
options: ComboboxOptionsType
placeHolderMessage: string
searchPlaceHolderMessage: string
notFoundMessage: string
open: boolean
setOpen: React.Dispatch<React.SetStateAction<boolean>>
}) => JSX.Element
}) {
const [open, setOpen] = useState(false)
return render({
value,
options,
placeHolderMessage,
searchPlaceHolderMessage,
notFoundMessage,
open,
setOpen
})
}
export { Combobox, ComboboxRoot, ComboboxTrigger, ComboboxContent, CommandItem as ComboboxItem }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment