@hitachivantara/uikit-react-core
Version:
Core React components for the NEXT Design System.
315 lines (314 loc) • 10.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const jsxRuntime = require("react/jsx-runtime");
const React = require("react");
const utils$1 = require("@mui/material/utils");
const uikitReactUtils = require("@hitachivantara/uikit-react-utils");
const LabelContainer = require("../FormElement/LabelContainer.cjs");
const useControlled = require("../hooks/useControlled.cjs");
const useLabels = require("../hooks/useLabels.cjs");
const useUniqueId = require("../hooks/useUniqueId.cjs");
const generic = require("../types/generic.cjs");
const CounterLabel = require("../utils/CounterLabel.cjs");
const setId = require("../utils/setId.cjs");
const Dropdown_styles = require("./Dropdown.styles.cjs");
const utils = require("./utils.cjs");
const List = require("./List/List.cjs");
const FormElement = require("../FormElement/FormElement.cjs");
const BaseDropdown = require("../BaseDropdown/BaseDropdown.cjs");
const utils$2 = require("../FormElement/utils.cjs");
const WarningText = require("../FormElement/WarningText/WarningText.cjs");
const Typography = require("../Typography/Typography.cjs");
const DEFAULT_LABELS = {
/** Label for overwrite the default header behavior. */
select: void 0,
/** Label used for the All checkbox action. @deprecated unused */
selectAll: "All",
/** Cancel button label. */
cancelLabel: "Cancel",
/** Apply button label. */
applyLabel: "Apply",
/** The label used in the middle of the multiSelection count. */
searchPlaceholder: "Search",
/** The label used in search. */
multiSelectionConjunction: "/"
};
const HvDropdown = generic.fixedForwardRef(function HvDropdown2(props, ref) {
const {
classes: classesProp,
className,
id,
name,
required,
disabled,
readOnly,
label,
"aria-label": ariaLabel,
"aria-labelledby": ariaLabelledBy,
description,
"aria-describedby": ariaDescribedBy,
placeholder = "Select...",
onChange,
status,
statusMessage,
"aria-errormessage": ariaErrorMessage,
onCancel,
onToggle,
onClickOutside,
onFocus,
onBlur,
values,
multiSelect = false,
showSearch,
expanded,
defaultExpanded,
notifyChangesOnFirstRender,
labels: labelsProp,
hasTooltips,
disablePortal,
singleSelectionToggle = true,
placement,
variableWidth,
popperProps = {},
height,
maxHeight,
virtualized,
baseDropdownProps = {},
listProps = {},
...others
} = uikitReactUtils.useDefaultProps("HvDropdown", props);
const { classes, cx } = Dropdown_styles.useClasses(classesProp);
const labels = useLabels.useLabels(DEFAULT_LABELS, labelsProp);
const elementId = useUniqueId.useUniqueId(id);
const [validationState, setValidationState] = useControlled.useControlled(
status,
"standBy"
);
const [validationMessage] = useControlled.useControlled(statusMessage, "Required");
const [isOpen, setIsOpen] = useControlled.useControlled(expanded, Boolean(defaultExpanded));
const [selectionLabel, setSelectionLabel] = React.useState(
utils.getSelectionLabel(labels, placeholder, multiSelect, values)
);
const [internalValues, setInternalValues] = React.useState(values);
const internalValuesRef = React.useRef(values);
React.useEffect(() => {
setInternalValues(values);
internalValuesRef.current = values;
}, [values]);
React.useEffect(() => {
setSelectionLabel(
utils.getSelectionLabel(labels, placeholder, multiSelect, values)
);
}, [labels, multiSelect, placeholder, values]);
const dropdownHeaderRef = React.useRef(void 0);
const {
ref: refProp,
dropdownHeaderRef: dropdownHeaderRefProp,
...otherBaseDropdownProps
} = baseDropdownProps;
const headerForkedRef = utils$1.useForkRef(dropdownHeaderRefProp, dropdownHeaderRef);
const dropdownForkedRef = utils$1.useForkRef(ref, refProp);
const handleToggle = (event, open) => {
onToggle?.(event, open);
setIsOpen(open);
if (!open) {
setValidationState(() => {
if (required) {
const hasSelection = utils.getSelected(internalValuesRef.current).length > 0;
if (!hasSelection) {
return "invalid";
}
}
return "valid";
});
}
};
const handleSelection = (listValues, commitChanges, toggle, notifyChanges = true) => {
const selected = utils.getSelected(listValues);
if (commitChanges) {
setInternalValues(listValues);
internalValuesRef.current = listValues;
setSelectionLabel(
utils.getSelectionLabel(labels, placeholder, multiSelect, listValues)
);
setValidationState(() => {
if (required && selected.length === 0) {
return "invalid";
}
return "valid";
});
}
if (notifyChanges) {
onChange?.(multiSelect ? selected : selected[0]);
}
if (toggle) {
handleToggle(void 0, false);
dropdownHeaderRef.current?.focus({ preventScroll: true });
}
};
const handleCancel = (evt) => {
onCancel?.(evt);
handleToggle(evt, false);
dropdownHeaderRef.current?.focus({ preventScroll: true });
};
const handleClickOutside = (evt) => {
onClickOutside?.(evt);
onCancel?.(evt);
};
const setFocusToContent = (containerRef) => {
const inputs = containerRef?.getElementsByTagName("input");
if (inputs && inputs.length > 0) {
inputs[0].focus();
return;
}
const listItems = containerRef != null ? [...containerRef.getElementsByTagName("li")] : [];
listItems.every((listItem) => {
if (listItem.tabIndex >= 0) {
listItem.focus();
return false;
}
return true;
});
};
const buildHeaderLabel = () => {
const hasSelection = utils.getSelected(internalValues).length > 0;
return labels?.select || !multiSelect ? /* @__PURE__ */ jsxRuntime.jsx(
Typography.HvTypography,
{
component: "div",
variant: "body",
className: cx(classes.placeholder, {
[classes.selectionDisabled]: disabled,
[classes.placeholderClosed]: !(isOpen || hasSelection)
}),
children: selectionLabel.selected
}
) : /* @__PURE__ */ jsxRuntime.jsx(
CounterLabel.CounterLabel,
{
selected: selectionLabel.selected,
total: selectionLabel.total,
conjunctionLabel: labels.multiSelectionConjunction,
className: cx(classes.placeholder, {
[classes.selectionDisabled]: disabled
})
}
);
};
const canShowError = ariaErrorMessage == null && (status !== void 0 && statusMessage !== void 0 || status === void 0 && required);
const isStateInvalid = utils$2.isInvalid(validationState);
let errorMessageId;
if (isStateInvalid) {
errorMessageId = canShowError ? setId.setId(elementId, "error") : ariaErrorMessage;
}
return /* @__PURE__ */ jsxRuntime.jsxs(
FormElement.HvFormElement,
{
id,
name,
status: validationState,
disabled,
readOnly,
required,
className: cx(
classes.root,
{
[classes.disabled]: disabled
},
className
),
...others,
children: [
/* @__PURE__ */ jsxRuntime.jsx(
LabelContainer.HvLabelContainer,
{
label,
description,
labelId: setId.setId(elementId, "label"),
descriptionId: setId.setId(elementId, "description"),
classes: {
root: classes.labelContainer,
label: classes.label,
description: classes.description
}
}
),
/* @__PURE__ */ jsxRuntime.jsx(
BaseDropdown.HvBaseDropdown,
{
ref: dropdownForkedRef,
id: setId.setId(id, "dropdown"),
classes: {
root: cx(classes.dropdown, {
[classes.readOnly]: readOnly
}),
arrow: classes.arrow,
header: cx(classes.dropdownHeader, {
[classes.dropdownHeaderInvalid]: isStateInvalid
}),
headerOpen: classes.dropdownHeaderOpen
},
expanded: isOpen,
disabled,
readOnly,
required,
disablePortal,
placement,
popperProps,
placeholder: buildHeaderLabel(),
onToggle: handleToggle,
onClickOutside: handleClickOutside,
onContainerCreation: setFocusToContent,
role: "combobox",
variableWidth,
"aria-label": ariaLabel,
"aria-labelledby": [label && setId.setId(elementId, "label"), ariaLabelledBy].join(" ").trim() || void 0,
"aria-invalid": isStateInvalid ? true : void 0,
"aria-errormessage": errorMessageId,
"aria-describedby": [description && setId.setId(elementId, "description"), ariaDescribedBy].join(" ").trim() || void 0,
onFocus,
onBlur,
dropdownHeaderRef: headerForkedRef,
...otherBaseDropdownProps,
children: /* @__PURE__ */ jsxRuntime.jsx(
List.HvDropdownList,
{
id: setId.setId(elementId, "values"),
classes: {
rootList: classes.rootList,
dropdownListContainer: classes.dropdownListContainer
},
values: internalValues,
multiSelect,
showSearch,
onChange: handleSelection,
onCancel: handleCancel,
labels,
notifyChangesOnFirstRender,
hasTooltips,
singleSelectionToggle,
"aria-label": ariaLabel,
"aria-labelledby": label ? setId.setId(elementId, "label") : void 0,
height,
maxHeight,
virtualized,
...listProps
}
)
}
),
canShowError && /* @__PURE__ */ jsxRuntime.jsx(
WarningText.HvWarningText,
{
id: setId.setId(elementId, "error"),
disableBorder: true,
className: classes.error,
children: validationMessage
}
)
]
}
);
});
exports.dropdownClasses = Dropdown_styles.staticClasses;
exports.HvDropdown = HvDropdown;