"use client";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { cnb } from "cnbuilder";
import { useMemo, useRef, useState } from "react";
import { IconRotator } from "../icon/IconRotator.js";
import { getIcon } from "../icon/iconConfig.js";
import { Menu } from "../menu/Menu.js";
import { KeyboardMovementProvider } from "../movement/useKeyboardMovementProvider.js";
import { useEnsuredId } from "../useEnsuredId.js";
import { useEnsuredRef } from "../useEnsuredRef.js";
import { label as labelStyles } from "./Label.js";
import { SelectedOption } from "./SelectedOption.js";
import { TextFieldContainer } from "./TextFieldContainer.js";
import { getFormConfig } from "./formConfig.js";
import { select } from "./selectStyles.js";
import { extractOptionsFromChildren } from "./selectUtils.js";
import { textField } from "./textFieldStyles.js";
import { useFormReset } from "./useFormReset.js";
import { ListboxProvider } from "./useListboxProvider.js";
import { useSelectCombobox } from "./useSelectCombobox.js";
const EMPTY_STRING = "";
const noop = ()=>{
// do nothing
};
/**
 * **Client Component**
 *
 * @example
 * Simple Example
 * ```tsx
 * import { Select, Option } from "react-md";
 * import { useState, type ReactElement } from "react";
 *
 * function Example(): ReactElement {
 *   const [value, setValue] = useState("");
 *
 *   return (
 *     <Select
 *       label="Select"
 *       value={value}
 *       onChange={(event) => setValue(event.currentTarget.value)}
 *       placeholder="Select a value"
 *     >
 *       <Option value="a">Option 1</Option>
 *       <Option value="b">Option 2</Option>
 *       <Option value="c">Option 3</Option>
 *       <Option value="d">Option 4</Option>
 *     </Select>
 *   );
 * }
 * ```
 *
 * @example
 * Testing
 * ```tsx
 * rmdRender(
 *   <Select label="Select" selectedOptionProps={{ "data-testid": "selected" }}>
 *     <Option value="a">Option 1</Option>
 *     <Option value="b">Option 2</Option>
 *     <Option value="c">Option 3</Option>
 *     <Option value="d">Option 4</Option>
 *   </Select>
 * );
 *
 * const user = userEvent.setup();
 * const select = screen.getByRole("combobox", { name: "Select" });
 * const selected = screen.getByTestId("selected")
 * const selectInput = screen.getByRole("textbox", { hidden: true });
 * expect(selected).toHaveTextContent("");
 * expect(selectInput).toHaveValue("");
 *
 * await user.click(select);
 * await user.click(screen.getByRole("option"), { name: "Option 2" });
 *
 * expect(selected).toHaveTextContent("Option 2");
 * expect(selectInput).toHaveValue("b");
 * ```
 *
 * @remarks \@since 6.0.0 Rewritten with a new API.
 */ export function Select(props) {
    const { id, form, autoCompleteValue, autoComplete = autoCompleteValue, name = autoCompleteValue, className, onClick, onFocus, onKeyDown, inputRef: propInputRef, inputProps, containerRef, placeholder, menuProps = {}, label, labelProps = {}, selectedOptionProps, icon: propIcon, value, defaultValue, theme: propTheme, onChange = noop, rightAddon: propRightAddon, active = false, required, selectedIconAfter = false, disableOptionAddon = false, disableSelectedIcon = false, children, ...remaining } = props;
    const { dense, error, disabled } = props;
    const comboboxId = useEnsuredId(id, "select");
    const inputId = useEnsuredId(inputProps?.id, "select-value");
    const selectLabelId = useEnsuredId(labelProps.id, "select-label");
    const labelId = label ? selectLabelId : undefined;
    const [localValue, setLocalValue] = useState(()=>{
        if (typeof defaultValue !== "undefined") {
            return defaultValue;
        }
        return typeof value !== "undefined" ? value : EMPTY_STRING;
    });
    const currentValue = typeof value === "undefined" ? localValue : value;
    const initialValue = useRef(currentValue);
    const { options, currentOption } = extractOptionsFromChildren(children, currentValue);
    const { visible, comboboxProps, movementContext, getMenuProps } = useSelectCombobox({
        form,
        value: currentValue,
        values: options,
        onClick,
        onFocus,
        onKeyDown,
        disabled,
        popupId: menuProps.id,
        popupRef: menuProps.nodeRef,
        comboboxId,
        comboboxRef: containerRef
    });
    const [inputRef, inputRefCallback] = useEnsuredRef(propInputRef);
    useFormReset({
        form,
        elementRef: inputRef,
        defaultValue: initialValue.current
    });
    const listboxContext = useMemo(()=>({
            inputRef,
            currentValue,
            selectedIconAfter,
            disableSelectedIcon
        }), [
        currentValue,
        disableSelectedIcon,
        inputRef,
        selectedIconAfter
    ]);
    const icon = getIcon("dropdown", propIcon);
    const theme = getFormConfig("theme", propTheme);
    let rightAddon = propRightAddon;
    if (typeof rightAddon === "undefined" && icon) {
        rightAddon = /*#__PURE__*/ _jsx(IconRotator, {
            rotated: visible,
            children: icon
        });
    }
    let listboxLabelledBy = menuProps["aria-labelledby"];
    const listboxLabel = menuProps["aria-label"];
    if (!listboxLabel && !listboxLabelledBy) {
        listboxLabelledBy = labelId || comboboxId;
    }
    return /*#__PURE__*/ _jsx(ListboxProvider, {
        value: listboxContext,
        children: /*#__PURE__*/ _jsxs(KeyboardMovementProvider, {
            value: movementContext,
            children: [
                /*#__PURE__*/ _jsxs(TextFieldContainer, {
                    "aria-labelledby": labelId,
                    ...remaining,
                    ...comboboxProps,
                    label: !!label,
                    theme: theme,
                    active: active || visible,
                    className: cnb("rmd-select-container", className),
                    rightAddon: rightAddon,
                    children: [
                        /*#__PURE__*/ _jsx(SelectedOption, {
                            option: currentOption,
                            placeholder: placeholder,
                            disableAddon: disableOptionAddon,
                            ...selectedOptionProps
                        }),
                        /*#__PURE__*/ _jsx("input", {
                            "aria-hidden": true,
                            id: inputId,
                            ref: inputRefCallback,
                            type: "text",
                            autoComplete: autoComplete,
                            name: name,
                            tabIndex: -1,
                            disabled: disabled,
                            required: required,
                            placeholder: " ",
                            ...inputProps,
                            value: value,
                            defaultValue: defaultValue,
                            className: cnb(select({
                                theme
                            }), textField()),
                            onChange: (event)=>{
                                onChange(event);
                                if (typeof value !== "undefined") {
                                    return;
                                }
                                const nextValue = event.currentTarget.value;
                                const nextOption = options.find((option)=>option === nextValue);
                                setLocalValue(nextOption ?? initialValue.current);
                            }
                        }),
                        label && /*#__PURE__*/ _jsx("span", {
                            ...labelProps,
                            id: labelId,
                            className: labelStyles({
                                dense,
                                error,
                                disabled,
                                active: active || visible,
                                floating: true,
                                floatingActive: !!placeholder || !!currentOption,
                                className: labelProps.className
                            }),
                            children: label
                        })
                    ]
                }),
                /*#__PURE__*/ _jsx(Menu, {
                    ...getMenuProps(menuProps),
                    "aria-label": listboxLabel,
                    "aria-labelledby": listboxLabelledBy,
                    children: children
                })
            ]
        })
    });
}

//# sourceMappingURL=Select.js.map