@heroui/select
Version:
A select displays a collapsible list of options and allows a user to select one of them.
122 lines (119 loc) • 4.45 kB
JavaScript
"use client";
import {
HiddenSelect
} from "./chunk-YVPTWIXA.mjs";
import {
useSelect
} from "./chunk-ONGPOZUT.mjs";
// src/select.tsx
import { Listbox } from "@heroui/listbox";
import { FreeSoloPopover } from "@heroui/popover";
import { ChevronDownIcon } from "@heroui/shared-icons";
import { Spinner } from "@heroui/spinner";
import { useMemo } from "react";
import { forwardRef } from "@heroui/system";
import { ScrollShadow } from "@heroui/scroll-shadow";
import { cloneElement } from "react";
import { VisuallyHidden } from "@react-aria/visually-hidden";
import { AnimatePresence } from "framer-motion";
import { jsx, jsxs } from "react/jsx-runtime";
var Select = forwardRef(function Select2(props, ref) {
const {
Component,
state,
label,
hasHelper,
isLoading,
triggerRef,
selectorIcon = /* @__PURE__ */ jsx(ChevronDownIcon, {}),
description,
errorMessage,
isInvalid,
startContent,
endContent,
placeholder,
renderValue,
shouldLabelBeOutside,
disableAnimation,
getBaseProps,
getLabelProps,
getTriggerProps,
getValueProps,
getListboxProps,
getPopoverProps,
getSpinnerProps,
getMainWrapperProps,
getInnerWrapperProps,
getHiddenSelectProps,
getHelperWrapperProps,
getListboxWrapperProps,
getDescriptionProps,
getErrorMessageProps,
getSelectorIconProps
} = useSelect({ ...props, ref });
const labelContent = label ? /* @__PURE__ */ jsx("label", { ...getLabelProps(), children: label }) : null;
const clonedIcon = cloneElement(selectorIcon, getSelectorIconProps());
const helperWrapper = useMemo(() => {
const shouldShowError = isInvalid && errorMessage;
const hasContent = shouldShowError || description;
if (!hasHelper || !hasContent) return null;
return /* @__PURE__ */ jsx("div", { ...getHelperWrapperProps(), children: shouldShowError ? /* @__PURE__ */ jsx("div", { ...getErrorMessageProps(), children: errorMessage }) : /* @__PURE__ */ jsx("div", { ...getDescriptionProps(), children: description }) });
}, [
hasHelper,
isInvalid,
errorMessage,
description,
getHelperWrapperProps,
getErrorMessageProps,
getDescriptionProps
]);
const renderSelectedItem = useMemo(() => {
var _a;
if (!((_a = state.selectedItems) == null ? void 0 : _a.length)) return placeholder;
if (renderValue && typeof renderValue === "function") {
const mappedItems = [...state.selectedItems].map((item) => ({
key: item.key,
data: item.value,
type: item.type,
props: item.props,
textValue: item.textValue,
rendered: item.rendered,
"aria-label": item["aria-label"]
}));
return renderValue(mappedItems);
}
return state.selectedItems.map((item) => item.textValue).join(", ");
}, [state.selectedItems, renderValue, placeholder]);
const renderIndicator = useMemo(() => {
if (isLoading) {
return /* @__PURE__ */ jsx(Spinner, { ...getSpinnerProps() });
}
return clonedIcon;
}, [isLoading, clonedIcon, getSpinnerProps]);
const popoverContent = useMemo(
() => state.isOpen ? /* @__PURE__ */ jsx(FreeSoloPopover, { ...getPopoverProps(), children: /* @__PURE__ */ jsx(ScrollShadow, { ...getListboxWrapperProps(), children: /* @__PURE__ */ jsx(Listbox, { ...getListboxProps() }) }) }) : null,
[state.isOpen, getPopoverProps, state, triggerRef, getListboxWrapperProps, getListboxProps]
);
return /* @__PURE__ */ jsxs("div", { ...getBaseProps(), children: [
/* @__PURE__ */ jsx(HiddenSelect, { ...getHiddenSelectProps() }),
shouldLabelBeOutside ? labelContent : null,
/* @__PURE__ */ jsxs("div", { ...getMainWrapperProps(), children: [
/* @__PURE__ */ jsxs(Component, { ...getTriggerProps(), children: [
!shouldLabelBeOutside ? labelContent : null,
/* @__PURE__ */ jsxs("div", { ...getInnerWrapperProps(), children: [
startContent,
/* @__PURE__ */ jsx("span", { ...getValueProps(), children: renderSelectedItem }),
endContent && state.selectedItems && /* @__PURE__ */ jsx(VisuallyHidden, { elementType: "span", children: "," }),
endContent
] }),
renderIndicator
] }),
helperWrapper
] }),
disableAnimation ? popoverContent : /* @__PURE__ */ jsx(AnimatePresence, { children: popoverContent })
] });
});
var select_default = Select;
export {
select_default
};