import { Select as Kobalte } from "@kobalte/core/select" import { createMemo, type ComponentProps } from "solid-js" import { Icon, Button, type ButtonProps } from "@opencode-ai/ui" import { pipe, groupBy, entries, map } from "remeda" export interface SelectProps { placeholder?: string options: T[] current?: T value?: (x: T) => string label?: (x: T) => string groupBy?: (x: T) => string onSelect?: (value: T | undefined) => void class?: ComponentProps<"div">["class"] classList?: ComponentProps<"div">["classList"] } export function Select(props: SelectProps & ButtonProps) { const grouped = createMemo(() => { const result = pipe( props.options, groupBy((x) => (props.groupBy ? props.groupBy(x) : "")), // mapValues((x) => x.sort((a, b) => a.title.localeCompare(b.title))), entries(), map(([k, v]) => ({ category: k, options: v })), ) return result }) return ( data-component="select" value={props.current} options={grouped()} optionValue={(x) => (props.value ? props.value(x) : (x as string))} optionTextValue={(x) => (props.label ? props.label(x) : (x as string))} optionGroupChildren="options" placeholder={props.placeholder} sectionComponent={(props) => ( {props.section.rawValue.category} )} itemComponent={(itemProps) => ( {props.label ? props.label(itemProps.item.rawValue) : (itemProps.item.rawValue as string)} )} onChange={(v) => { props.onSelect?.(v ?? undefined) }} > data-slot="value"> {(state) => { const selected = state.selectedOption() ?? props.current if (!selected) return props.placeholder || "" if (props.label) return props.label(selected) return selected as string }} ) }