import { Cloud } from "lucide-react" import type { ComponentProps, ElementRef, ReactNode } from "react" import { useEffect, useRef, useState } from "react" import { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, } from "@/components/ui/command" import { Dialog, DialogContent, DialogTitle, DialogTrigger, } from "@/components/ui/dialog" import { cn } from "@/lib/utils" export type ModelSelectorProps = ComponentProps export const ModelSelector = (props: ModelSelectorProps) => ( ) export type ModelSelectorTriggerProps = ComponentProps export const ModelSelectorTrigger = (props: ModelSelectorTriggerProps) => ( ) export type ModelSelectorContentProps = ComponentProps & { title?: ReactNode } export const ModelSelectorContent = ({ className, children, title = "Model Selector", ...props }: ModelSelectorContentProps) => ( {title} {children} ) export type ModelSelectorDialogProps = ComponentProps export const ModelSelectorDialog = (props: ModelSelectorDialogProps) => ( ) export type ModelSelectorInputProps = ComponentProps export const ModelSelectorInput = ({ className, ...props }: ModelSelectorInputProps) => ( ) export type ModelSelectorListProps = ComponentProps export const ModelSelectorList = ({ className, ...props }: ModelSelectorListProps) => { const listRef = useRef>(null) const [showShadow, setShowShadow] = useState(false) useEffect(() => { const listElement = listRef.current if (!listElement) return const checkScroll = () => { const { scrollTop, scrollHeight, clientHeight } = listElement // Show shadow if there is more content below // Using a small threshold to handle fractional pixel rendering setShowShadow( scrollHeight > Math.ceil(scrollTop + clientHeight) + 1, ) } // Initial check checkScroll() // Event listeners listElement.addEventListener("scroll", checkScroll) window.addEventListener("resize", checkScroll) // Observe content changes (e.g. async loading of items) const observer = new MutationObserver(checkScroll) observer.observe(listElement, { childList: true, subtree: true }) return () => { listElement.removeEventListener("scroll", checkScroll) window.removeEventListener("resize", checkScroll) observer.disconnect() } }, []) return (
{/* Bottom shadow indicator for scrollable content */}
) } export type ModelSelectorEmptyProps = ComponentProps export const ModelSelectorEmpty = (props: ModelSelectorEmptyProps) => ( ) export type ModelSelectorGroupProps = ComponentProps export const ModelSelectorGroup = (props: ModelSelectorGroupProps) => ( ) export type ModelSelectorItemProps = ComponentProps export const ModelSelectorItem = (props: ModelSelectorItemProps) => ( ) export type ModelSelectorShortcutProps = ComponentProps export const ModelSelectorShortcut = (props: ModelSelectorShortcutProps) => ( ) export type ModelSelectorSeparatorProps = ComponentProps< typeof CommandSeparator > export const ModelSelectorSeparator = (props: ModelSelectorSeparatorProps) => ( ) export type ModelSelectorLogoProps = Omit< ComponentProps<"img">, "src" | "alt" > & { provider: string } export const ModelSelectorLogo = ({ provider, className, ...props }: ModelSelectorLogoProps) => { // Use Lucide icon for bedrock since models.dev doesn't have a good AWS icon if (provider === "amazon-bedrock") { return } return ( // biome-ignore lint/performance/noImgElement: External URL from models.dev {`${provider} ) } export type ModelSelectorLogoGroupProps = ComponentProps<"div"> export const ModelSelectorLogoGroup = ({ className, ...props }: ModelSelectorLogoGroupProps) => (
img]:rounded-full [&>img]:bg-background [&>img]:p-px [&>img]:ring-1 dark:[&>img]:bg-foreground", className, )} {...props} /> ) export type ModelSelectorNameProps = ComponentProps<"span"> export const ModelSelectorName = ({ className, ...props }: ModelSelectorNameProps) => ( ) export type ModelSelectorSectionHeaderProps = { icon: ReactNode label: string className?: string } export const ModelSelectorSectionHeader = ({ icon, label, className, }: ModelSelectorSectionHeaderProps) => (
{label}
)