{"version":3,"file":"select.cjs","sources":["../../../src/components/select.tsx"],"sourcesContent":["import React, {\n    type ReactElement,\n    type ForwardedRef,\n    useCallback,\n    useState,\n    useRef,\n    forwardRef,\n    useId,\n    type ChangeEvent,\n    useEffect,\n    useMemo,\n} from \"react\";\nimport type { BaseInputProps } from \"./commons/input\";\nimport ChevronUp from \"../icons/chevron-up\";\nimport ChevronDown from \"../icons/chevron-down\";\nimport { Popover } from \"./popover\";\nimport { TextInput } from \"./text-input\";\nimport { useClickAway, useDebounce } from \"react-use\";\nimport { mergedCva, mergedCx } from \"../utils/components\";\nimport { FixedSizeList, type ListChildComponentProps } from \"react-window\";\nimport { Typography } from \"./typography\";\n\nconst dropdownRootStyles = mergedCva(\n    [\n        \"cui-rounded-xxl\",\n        \"cui-border\",\n        \"cui-border-black\",\n        \"cui-max-h-48\",\n        \"cui-bg-white\",\n        \"dark:cui-bg-black\",\n        \"dark:cui-border-white\",\n        \"cui-z-20\",\n        \"cui-overflow-hidden\",\n        \"cui-h-fit\",\n    ],\n    {\n        variants: {\n            empty: {\n                true: [\"cui-h-fit\"],\n            },\n        },\n    },\n);\n\nconst emptyOptionListStyles = mergedCva([\n    \"cui-flex\",\n    \"cui-justify-center\",\n    \"cui-items-center\",\n    \"cui-p-3\",\n    \"cui-h-12\",\n]);\n\nconst optionListStyles = mergedCva([\"cui-scrollbar\"]);\n\nconst optionStyles = mergedCva(\n    [\n        \"cui-cursor-pointer\",\n        \"cui-p-3\",\n        \"cui-h-12\",\n        \"cui-font-mono\",\n        \"cui-font-normal\",\n        \"cui-outline-none\",\n        \"cui-placeholder-opacity-20\",\n        \"dark:cui-placeholder-opacity-30\",\n        \"cui-text-black\",\n        \"dark:cui-text-white\",\n        \"cui-box-border\",\n        \"hover:cui-bg-gray-200\",\n        \"dark:hover:cui-bg-gray-700\",\n    ],\n    {\n        variants: {\n            picked: {\n                true: [\n                    \"cui-bg-gray-300\",\n                    \"hover:cui-bg-gray-300\",\n                    \"dark:cui-bg-gray-600\",\n                    \"dark:hover:cui-bg-gray-600\",\n                ],\n            },\n        },\n        defaultVariants: {\n            picked: false,\n        },\n    },\n);\n\nconst customOptionWrapperStyles = mergedCva([\"cui-pointer-events-none\"]);\n\nexport type ValueType = string | number;\n\nexport interface SelectOption<V extends ValueType> {\n    label: string;\n    value: V;\n    disabled?: boolean;\n}\n\nexport interface ClassName extends Pick<BaseInputProps<unknown>, \"className\"> {\n    inputRoot?: string;\n    wrapper?: string;\n    dropdownRoot?: string;\n    listWrapper?: string;\n    emptyList?: string;\n    list?: string;\n    option?: string;\n    customOptionWrapper?: string;\n}\n\nexport type SelectProps<T extends SelectOption<ValueType>> = {\n    id?: string;\n    options: T[];\n    value: T | null;\n    search?: boolean;\n    onChange: (value: T) => void;\n    renderOption?: (value: T) => ReactElement;\n    loading?: boolean;\n    messages: {\n        noResults: string;\n    };\n    dataTestIds?: {\n        textInput?: string;\n        option?: string;\n    };\n    className?: ClassName;\n} & Omit<BaseInputProps<unknown>, \"onChange\" | \"value\" | \"id\">;\n\ntype ItemData<T extends SelectOption<ValueType>> = Pick<\n    SelectProps<T>,\n    \"options\" | \"value\" | \"onChange\" | \"renderOption\"\n> & {\n    dataTestIds?: {\n        option?: string;\n    };\n    className?: Pick<ClassName, \"option\" | \"customOptionWrapper\">;\n};\n\nfunction Component<T extends SelectOption<ValueType>>(\n    {\n        id,\n        options,\n        value,\n        search,\n        onChange,\n        className,\n        renderOption,\n        disabled,\n        loading,\n        messages,\n        dataTestIds,\n        ...rest\n    }: SelectProps<T>,\n    ref: ForwardedRef<HTMLInputElement>,\n): ReactElement {\n    const generatedId = useId();\n    const [anchorEl, setAnchorEl] = useState<HTMLDivElement | null>(null);\n    const dropdownRef = useRef<HTMLDivElement>(null);\n    const [open, setOpen] = useState(false);\n    const [query, setQuery] = useState(\"\");\n    const [debouncedQuery, setdebouncedQuery] = useState(query);\n    const [filteredOptions, setFilteredOptions] = useState(options);\n\n    const resolvedId = id || generatedId;\n\n    useClickAway(dropdownRef, () => {\n        setOpen(false);\n        setQuery(\"\");\n    });\n\n    useEffect(() => {\n        setFilteredOptions(\n            options.filter((option) =>\n                option.label\n                    .toLowerCase()\n                    .includes(debouncedQuery.toLowerCase()),\n            ),\n        );\n    }, [debouncedQuery, options]);\n\n    useDebounce(\n        () => {\n            setdebouncedQuery(query);\n        },\n        200,\n        [query],\n    );\n\n    const handleClick = useCallback(() => {\n        if (!open && (disabled || loading)) return;\n        setOpen(!open);\n    }, [disabled, loading, open]);\n\n    const handleChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n        setQuery(e.target.value);\n    }, []);\n\n    const handleInnerChange = useCallback(\n        (item: T) => {\n            setOpen(false);\n            onChange(item);\n        },\n        [onChange],\n    );\n\n    const itemData = useMemo(() => {\n        const data: ItemData<T> = {\n            options: filteredOptions,\n            onChange: handleInnerChange,\n            value,\n            className,\n            renderOption,\n            dataTestIds: {\n                option: dataTestIds?.option,\n            },\n        };\n        return data;\n    }, [\n        className,\n        handleInnerChange,\n        filteredOptions,\n        renderOption,\n        value,\n        dataTestIds,\n    ]);\n\n    return (\n        <div className={className?.root}>\n            <TextInput\n                data-testid={dataTestIds?.textInput}\n                ref={(element) => {\n                    if (ref) {\n                        if (typeof ref === \"function\") ref(element);\n                        else ref.current = element;\n                    }\n                    setAnchorEl(element);\n                }}\n                id={resolvedId}\n                readOnly={!search}\n                icon={open ? ChevronUp : ChevronDown}\n                value={open && search ? query : value?.label}\n                disabled={disabled}\n                loading={loading}\n                {...rest}\n                className={{\n                    ...className,\n                    input: `cui-cursor-pointer ${className?.input}`,\n                    inputIcon: `cui-w-4 ${className?.inputIcon}`,\n                }}\n                onChange={handleChange}\n                onClick={handleClick}\n            />\n            <Popover\n                anchor={anchorEl}\n                open={open}\n                placement=\"bottom-start\"\n                className={{\n                    root: dropdownRootStyles({\n                        empty: filteredOptions.length === 0,\n                        className: className?.dropdownRoot,\n                    }),\n                }}\n                ref={dropdownRef}\n            >\n                {filteredOptions.length === 0 ? (\n                    <div\n                        style={{\n                            width: anchorEl?.parentElement?.clientWidth,\n                        }}\n                        className={emptyOptionListStyles({\n                            className: className?.emptyList,\n                        })}\n                    >\n                        <Typography>{messages.noResults}</Typography>\n                    </div>\n                ) : (\n                    <FixedSizeList<ItemData<T>>\n                        height={Math.min(filteredOptions.length, 4) * 48}\n                        width={anchorEl?.parentElement?.clientWidth || \"auto\"}\n                        itemCount={filteredOptions.length}\n                        itemData={itemData}\n                        itemSize={48}\n                        className={optionListStyles({\n                            className: className?.list,\n                        })}\n                    >\n                        {OptionRow}\n                    </FixedSizeList>\n                )}\n            </Popover>\n        </div>\n    );\n}\n\nfunction OptionRow<T extends SelectOption<ValueType>>({\n    index,\n    style,\n    data: { onChange, options, className, value, renderOption, dataTestIds },\n}: ListChildComponentProps<ItemData<T>>) {\n    const item = options[index];\n\n    const handleClick = useCallback(() => {\n        onChange(item);\n    }, [item, onChange]);\n\n    return (\n        <div\n            data-testid={\n                dataTestIds?.option && `${dataTestIds.option}-${item.value}`\n            }\n            style={style}\n            className={optionStyles({\n                picked: value?.value === item.value,\n                className: className?.option,\n            })}\n            onClick={handleClick}\n        >\n            {!!renderOption ? (\n                <div\n                    className={mergedCx(\n                        customOptionWrapperStyles(),\n                        className?.customOptionWrapper,\n                    )}\n                >\n                    {renderOption(item)}\n                </div>\n            ) : (\n                item.label\n            )}\n        </div>\n    );\n}\n\nexport const Select = forwardRef(Component) as <\n    T extends SelectOption<ValueType>,\n>(\n    props: SelectProps<T> & { ref?: React.ForwardedRef<HTMLSelectElement> },\n) => ReturnType<typeof Component>;\n"],"names":["mergedCva","useId","useState","useRef","useEffect","useCallback","useMemo","TextInput","ChevronUp","ChevronDown","Popover","Typography","FixedSizeList","mergedCx","forwardRef"],"mappings":"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"}