import type { JSX, ValidComponent } from "@solidjs/web"; import { dynamic } from "@solidjs/web"; import { createMemo, omit, Show } from "solid-js"; import { composeRefs, userRef } from "../../internals/compose-refs"; import type { MutableRef } from "../../internals/floating-ui/types"; import { mergeRootProps } from "../../internals/merge-root-props"; import { useOpenChangeComplete } from "../../internals/popups/use-open-change-complete"; import { resolveClassStyle } from "../../internals/resolve-class-style"; import type { BaseUIComponentProps } from "../../internals/types"; import { type TransitionStatus, useTransitionStatus, } from "../../internals/use-transition-status/use-transition-status"; import { useComboboxItemContext } from "../item/item-context"; export interface ComboboxItemIndicatorState { selected: boolean; transitionStatus: TransitionStatus; } export interface ComboboxItemIndicatorProps extends BaseUIComponentProps<"span", ComboboxItemIndicatorState> { as?: ValidComponent; keepMounted?: boolean | undefined; children?: JSX.Element; } /** * Indicates whether the item is selected. Renders a ``. */ export function ComboboxItemIndicator( props: ComboboxItemIndicatorProps, ): JSX.Element { const item = useComboboxItemContext(); const keepMounted = (): boolean => props.keepMounted ?? false; const selected = item.selected; const indicatorRef: MutableRef = { current: null }; const { mounted, transitionStatus, setMounted } = useTransitionStatus( selected, () => true, () => false, ); useOpenChangeComplete({ open: selected, ref: indicatorRef, onComplete: () => { if (!selected()) setMounted(false); }, }); const state = createMemo(() => ({ selected: selected(), transitionStatus: transitionStatus(), })); const internal = { "aria-hidden": true, get children() { return props.children; }, get "data-starting-style"() { return state().transitionStatus === "starting" ? "" : undefined; }, get "data-ending-style"() { return state().transitionStatus === "ending" ? "" : undefined; }, }; const userClassStyle = resolveClassStyle(props, () => state()); const userProps = omit( props, "as", "class", "style", "attrs", "keepMounted", "children", ); let merged: Record = mergeRootProps( internal, userClassStyle, ); merged = mergeRootProps(merged, userProps); const setIndicatorRef = (el: HTMLElement | null): void => { indicatorRef.current = el; }; const Tag = dynamic(() => props.as ?? "span"); const element = ( ); return {element}; }