import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { Listbox, ListboxButton, ListboxOption, ListboxOptions } from "@headlessui/react";
import { X, Check, ChevronsUpDownIcon } from "lucide-react";
import clsx from "clsx";
import { useState, useEffect, useRef } from "react";
import { Button } from "./Button";
import { Center } from "./Center";
function getFilterByFn(filterBy) {
    if (!filterBy) {
        return (o) => String(o).toLowerCase();
    }
    else if (typeof filterBy === 'string') {
        return (o) => String(o[filterBy]).toLowerCase();
    }
    else {
        return filterBy;
    }
}
export function SelectBox({ clearTitle, ClearIcon = X, showFilter, filterBy, isClearable, disabled, by, options, value, onChange, className, addNew, addNewLabel, placeholder, optionLabel = (option) => String(option), label }) {
    const [filter, setFilter] = useState();
    const buttonRef = useRef(null);
    const [buttonWidth, setButtonWidth] = useState();
    useEffect(() => {
        if (buttonRef.current) {
            const resizeObserver = new ResizeObserver((entries) => {
                setButtonWidth(entries[0].contentRect.width);
            });
            resizeObserver.observe(buttonRef.current);
            return () => resizeObserver.disconnect();
        }
    }, []);
    const onClear = (e) => {
        e.preventDefault();
        e.stopPropagation();
        if (isClearable) {
            onChange(undefined);
        }
    };
    const onFilterChange = (e) => {
        setFilter(e.target.value);
    };
    let filteredOptions = options || [];
    if (showFilter === undefined) {
        showFilter = filteredOptions?.length >= 10;
    }
    if (showFilter && filter) {
        const filterLc = filter.toLowerCase();
        const filterFn = getFilterByFn(filterBy);
        filteredOptions = filteredOptions.filter(o => filterFn(o).includes(filterLc));
    }
    const onFilterKeyDown = (e) => {
        if (e.key !== "Escape"
            && e.key !== "Enter"
            && e.key !== "ArrowDown"
            && e.key !== "ArrowUp") {
            e.stopPropagation();
        }
    };
    return (_jsx(Listbox, { value: value ?? undefined, onChange: onChange, by: by, disabled: disabled, children: () => (_jsx("div", { className: 'overflow-y-visible ' + className, children: _jsxs("div", { className: "relative", children: [_jsxs(ListboxButton, { ref: buttonRef, className: "relative w-full cursor-default rounded-md bg-white py-1.5 text-left text-gray-900 shadow-2xs ring-1 ring-inset ring-gray-300 focus:outline-hidden focus:ring-2 focus:ring-indigo-600 dark:ring-slate-600 dark:text-slate-50 dark:bg-slate-800 sm:text-sm sm:leading-6 hover:cursor-pointer", children: [label && _jsx("div", { className: 'w-full text-gray-500 text-left px-2', children: label }), _jsx("span", { className: "block truncate pl-3 pr-14", children: value ? optionLabel(value) : placeholder }), isClearable && value != null && _jsx("span", { className: "absolute inset-y-0 right-0 mr-5 flex items-center pr-2", onClick: onClear, children: _jsx(ClearIcon, { title: clearTitle, className: "size-5 text-gray-400 hover:text-red-500 cursor-pointer", "aria-hidden": "true" }) }), !disabled &&
                                _jsx("span", { className: "pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2", children: _jsx(ChevronsUpDownIcon, { className: "size-5 text-gray-400", "aria-hidden": "true" }) })] }), _jsxs(ListboxOptions, { anchor: "bottom", style: { width: buttonWidth, zIndex: 100000000 }, className: "absolute z-10 mt-1 overflow-auto rounded-md bg-white dark:ring-slate-600 dark:text-slate-50 dark:bg-slate-800 py-1 text-base shadow-lg ring-1 ring-gray-300 ring-opacity-5 focus:outline-hidden sm:text-sm", children: [showFilter &&
                                _jsx("div", { className: "p-1", children: _jsx("input", { type: "text", value: filter || '', onKeyDown: onFilterKeyDown, onChange: onFilterChange, className: "w-full p-1 border border-gray-300 rounded-md dark:bg-slate-700 dark:text-slate-50", placeholder: "Filter..." }) }), _jsx("div", { className: "overflow-y-auto max-h-60", children: filteredOptions.map((option, i) => _jsx(ListOption, { option: option, optionLabel: optionLabel, className: "hover:cursor-pointer" }, i)) }), addNew &&
                                _jsx(Center, { className: "font-semibold py-2 border-t", children: _jsx(Button, { variant: 'secondary', onClick: addNew, children: addNewLabel }) })] })] }) })) }));
}
export function ListOption({ option, optionLabel, onClick, className }) {
    return (_jsx(ListboxOption, { className: ({ active }) => clsx(active ? 'bg-indigo-600 text-white dark:bg-indigo-800 dark:text-white' : 'text-gray-900 dark:text-slate-50', 'relative cursor-default select-none py-2 pl-3 pr-9', className), value: option, onClick: onClick, children: ({ selected, active }) => (_jsxs(_Fragment, { children: [_jsx("div", { className: clsx(selected ? 'font-semibold' : 'font-inherit', 'block truncate'), children: optionLabel(option) }), selected ? (_jsx("div", { className: clsx(active ? 'text-white' : 'text-indigo-600', 'absolute inset-y-0 right-0 flex items-center pr-4'), children: _jsx(Check, { className: "size-5", "aria-hidden": "true" }) })) : null] })) }));
}
//# sourceMappingURL=SelectBox.js.map