| 23 | } |
| 24 | |
| 25 | export function Select<T>(props: SelectProps<T> & Omit<ButtonProps, "children">) { |
| 26 | const [local, others] = splitProps(props, [ |
| 27 | "class", |
| 28 | "classList", |
| 29 | "placeholder", |
| 30 | "options", |
| 31 | "current", |
| 32 | "value", |
| 33 | "label", |
| 34 | "groupBy", |
| 35 | "valueClass", |
| 36 | "onSelect", |
| 37 | "onHighlight", |
| 38 | "onOpenChange", |
| 39 | "children", |
| 40 | "triggerStyle", |
| 41 | "triggerVariant", |
| 42 | "triggerProps", |
| 43 | ]) |
| 44 | |
| 45 | const state = { |
| 46 | key: undefined as string | undefined, |
| 47 | cleanup: undefined as (() => void) | void, |
| 48 | } |
| 49 | |
| 50 | const stop = () => { |
| 51 | state.cleanup?.() |
| 52 | state.cleanup = undefined |
| 53 | state.key = undefined |
| 54 | } |
| 55 | |
| 56 | const keyFor = (item: T) => (local.value ? local.value(item) : (item as string)) |
| 57 | |
| 58 | const move = (item: T | undefined) => { |
| 59 | if (!local.onHighlight) return |
| 60 | if (!item) { |
| 61 | stop() |
| 62 | return |
| 63 | } |
| 64 | |
| 65 | const key = keyFor(item) |
| 66 | if (state.key === key) return |
| 67 | state.cleanup?.() |
| 68 | state.cleanup = local.onHighlight(item) |
| 69 | state.key = key |
| 70 | } |
| 71 | |
| 72 | onCleanup(stop) |
| 73 | |
| 74 | const grouped = createMemo(() => { |
| 75 | const result = pipe( |
| 76 | local.options, |
| 77 | groupBy((x) => (local.groupBy ? local.groupBy(x) : "")), |
| 78 | // mapValues((x) => x.sort((a, b) => a.title.localeCompare(b.title))), |
| 79 | entries(), |
| 80 | map(([k, v]) => ({ category: k, options: v })), |
| 81 | ) |
| 82 | return result |