import { OverrideComponentProps, isFunction, mergeRefs } from "@kobalte/utils";
import {
type Accessor,
type JSX,
type ValidComponent,
children,
splitProps,
} from "solid-js";
import {
type FormControlDataSet,
useFormControlContext,
} from "../form-control";
import {
type ElementOf,
Polymorphic,
type PolymorphicProps,
} from "../polymorphic";
import { type ComboboxDataSet, useComboboxContext } from "./combobox-context";
export interface ComboboxControlState {
/** The selected options. */
selectedOptions: Accessor ;
/** A function to remove an option from the selection. */
remove: (option: Option) => void;
/** A function to clear the selection. */
clear: () => void;
}
export interface ComboboxControlOptions {
/**
* The children of the combobox control.
* Can be a `JSX.Element` or a _render prop_ for having access to the internal state.
*/
children?:
| JSX.Element
| ((state: ComboboxControlState ) => JSX.Element);
}
export interface ComboboxControlCommonProps<
T extends HTMLElement = HTMLElement,
> {
ref: T | ((el: T) => void);
}
export interface ComboboxControlRenderProps
extends ComboboxControlCommonProps,
FormControlDataSet,
ComboboxDataSet {
children: JSX.Element;
}
export type ComboboxControlProps<
Option,
T extends ValidComponent | HTMLElement = HTMLElement,
> = ComboboxControlOptions &
Partial>>;
/**
* Contains the combobox input and trigger.
*/
export function ComboboxControl(
props: PolymorphicProps>,
) {
const formControlContext = useFormControlContext();
const context = useComboboxContext();
const [local, others] = splitProps(props as ComboboxControlProps, [
"ref",
"children",
]);
const selectionManager = () => context.listState().selectionManager();
return (
as="div"
ref={mergeRefs(context.setControlRef, local.ref)}
{...context.dataset()}
{...formControlContext.dataset()}
{...others}
>
context.selectedOptions(),
remove: (option) => context.removeOptionFromSelection(option),
clear: () => selectionManager().clearSelection(),
}}
>
{local.children}
);
}
interface ComboboxControlChildProps
extends Pick, "children"> {
state: ComboboxControlState;
}
function ComboboxControlChild (
props: ComboboxControlChildProps ,
) {
const resolvedChildren = children(() => {
const body = props.children;
return isFunction(body) ? body(props.state) : body;
});
return <>{resolvedChildren()}>;
}