@hitachivantara/uikit-react-core
Version:
Core React components for the NEXT Design System.
237 lines (236 loc) • 7.85 kB
JavaScript
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const jsxRuntime = require("react/jsx-runtime");
const React = require("react");
const Popper = require("@mui/base/Popper");
const useSelect = require("@mui/base/useSelect");
const utils = require("@mui/material/utils");
const clsx = require("clsx");
const uikitReactUtils = require("@hitachivantara/uikit-react-utils");
const LabelContainer = require("../FormElement/LabelContainer.cjs");
const useUniqueId = require("../hooks/useUniqueId.cjs");
const generic = require("../types/generic.cjs");
const document = require("../utils/document.cjs");
const setId = require("../utils/setId.cjs");
const Option = require("./Option.cjs");
const Select_styles = require("./Select.styles.cjs");
const FormElement = require("../FormElement/FormElement.cjs");
const DropdownButton = require("../DropdownButton/DropdownButton.cjs");
const ListContainer = require("../ListContainer/ListContainer.cjs");
const WarningText = require("../FormElement/WarningText/WarningText.cjs");
function defaultRenderValue(options) {
if (Array.isArray(options)) {
if (options.length === 0) return null;
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: options.map((o) => o.label).join(", ") });
}
return options?.label ?? null;
}
const mergeIds = (...ids) => clsx.clsx(ids) || void 0;
function renderOptions(options) {
return options?.map((option) => /* @__PURE__ */ jsxRuntime.jsx(Option.HvOption, { ...option, children: option.label }, option.value));
}
const HvSelect = generic.fixedForwardRef(function HvSelect2(props, ref) {
const {
children: childrenProp,
classes: classesProp,
className,
id: idProp,
size,
variant = "secondarySubtle",
name,
required,
disabled: disabledProp,
readOnly,
label,
open: openProp,
defaultOpen,
multiple,
autoComplete,
options: optionsProp,
variableWidth,
value: valueProp,
defaultValue,
placeholder,
inputProps,
enablePortal,
"aria-label": ariaLabel,
"aria-labelledby": ariaLabelledBy,
description,
"aria-describedby": ariaDescribedBy,
status,
statusMessage,
"aria-errormessage": ariaErrorMessage,
getSerializedValue,
onClick,
onChange,
onOpenChange,
...others
} = uikitReactUtils.useDefaultProps("HvSelect", props);
const { classes, cx } = Select_styles.useClasses(classesProp);
const { rootId } = uikitReactUtils.useTheme();
const [placement, setPlacement] = React.useState("bottom-start");
const buttonRef = React.useRef(null);
const handleButtonRef = utils.useForkRef(ref, buttonRef);
const {
contextValue,
disabled,
getButtonProps,
getListboxProps,
getHiddenInputProps,
getOptionMetadata,
value,
open
} = useSelect.useSelect({
componentName: "HvSelect",
name,
required,
disabled: disabledProp,
multiple,
open: openProp,
defaultOpen,
value: valueProp,
defaultValue,
options: optionsProp,
buttonRef: handleButtonRef,
getSerializedValue,
onChange,
onOpenChange: handleOpenChange
});
const id = useUniqueId.useUniqueId(idProp);
const labelId = useUniqueId.useUniqueId(setId.setId(idProp, "label"));
const descriptionId = useUniqueId.useUniqueId(setId.setId(idProp, "description"));
const errorMessageId = useUniqueId.useUniqueId(setId.setId(idProp, "error"));
const [validationMessage] = utils.useControlled({
name: "HvSelect.statusMessage",
controlled: statusMessage,
default: "Required"
});
const [validationState, setValidationState] = utils.useControlled({
name: "HvSelect.status",
controlled: status,
default: "standBy"
});
function handleOpenChange(newOpen) {
if (!newOpen) {
const hasValue = multiple ? value.length > 0 : !!value;
setValidationState(required && !hasValue ? "invalid" : "valid");
}
onOpenChange?.(newOpen);
}
const canShowError = ariaErrorMessage == null && (status !== void 0 && statusMessage !== void 0 || status === void 0 && required);
const isInvalid = validationState === "invalid";
const actualValue = multiple ? value.map((v) => getOptionMetadata(v)).filter((v) => v !== void 0) : getOptionMetadata(value) ?? null;
const children = childrenProp ?? renderOptions(optionsProp);
const isOpen = open && !!children;
return /* @__PURE__ */ jsxRuntime.jsxs(
FormElement.HvFormElement,
{
name,
required,
disabled,
readOnly,
status: validationState,
className: cx(classes.root, className, {
[classes.disabled]: disabled,
[classes.readOnly]: readOnly
}),
...others,
children: [
/* @__PURE__ */ jsxRuntime.jsx(
LabelContainer.HvLabelContainer,
{
label,
description,
inputId: id,
labelId,
descriptionId,
classes: {
root: classes.labelContainer,
label: classes.label,
description: classes.description
}
}
),
/* @__PURE__ */ jsxRuntime.jsx(
DropdownButton.HvDropdownButton,
{
id,
open: isOpen,
disabled,
readOnly,
className: cx(classes.select, {
[classes.invalid]: validationState === "invalid"
}),
placement,
size,
variant,
"aria-label": ariaLabel,
"aria-labelledby": mergeIds(ariaLabelledBy, { [labelId]: label }),
"aria-invalid": isInvalid ? true : void 0,
"aria-errormessage": errorMessageId,
"aria-describedby": mergeIds(ariaDescribedBy, {
[descriptionId]: description
}),
...getButtonProps(),
children: defaultRenderValue(actualValue) ?? placeholder
}
),
/* @__PURE__ */ jsxRuntime.jsx(
Popper.Popper,
{
role: "none",
open: isOpen,
keepMounted: true,
disablePortal: !enablePortal,
container: enablePortal ? document.getContainerElement(rootId) : void 0,
anchorEl: buttonRef.current,
className: classes.popper,
placement,
modifiers: [
{
enabled: true,
phase: "main",
fn: ({ state }) => setPlacement(state.placement)
}
],
children: /* @__PURE__ */ jsxRuntime.jsx(
ListContainer.HvListContainer,
{
condensed: true,
selectable: true,
style: {
width: variableWidth ? "auto" : (buttonRef.current?.clientWidth || 0) + 2
},
className: cx(classes.panel, {
[classes.panelOpenedUp]: placement.includes("top"),
[classes.panelOpenedDown]: placement.includes("bottom")
}),
...getListboxProps(),
children: /* @__PURE__ */ jsxRuntime.jsx(useSelect.SelectProvider, { value: contextValue, children })
}
)
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"input",
{
...getHiddenInputProps(),
autoComplete,
...inputProps
}
),
canShowError && /* @__PURE__ */ jsxRuntime.jsx(
WarningText.HvWarningText,
{
id: errorMessageId,
disableBorder: true,
className: classes.error,
children: validationMessage
}
)
]
}
);
});
exports.selectClasses = Select_styles.staticClasses;
exports.HvSelect = HvSelect;