@hitachivantara/uikit-react-core
Version:
Core React components for the NEXT Design System.
224 lines (223 loc) • 8.26 kB
JavaScript
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const jsxRuntime = require("react/jsx-runtime");
const React = require("react");
const utils = require("@mui/material/utils");
const uikitReactUtils = require("@hitachivantara/uikit-react-utils");
const useControlled = require("../hooks/useControlled.cjs");
const useUniqueId = require("../hooks/useUniqueId.cjs");
const keyboardUtils = require("../utils/keyboardUtils.cjs");
const multiSelectionEventHandler = require("../utils/multiSelectionEventHandler.cjs");
const setId = require("../utils/setId.cjs");
const SelectionList_styles = require("./SelectionList.styles.cjs");
const Label = require("../FormElement/Label/Label.cjs");
const InfoMessage = require("../FormElement/InfoMessage/InfoMessage.cjs");
const FormElement = require("../FormElement/FormElement.cjs");
const ListContainer = require("../ListContainer/ListContainer.cjs");
const WarningText = require("../FormElement/WarningText/WarningText.cjs");
const getValueFromSelectedChildren = (children, multiple) => {
const selectedValues = React.Children.toArray(children).map((child) => {
const childIsControlled = child?.props?.selected !== void 0;
const childIsSelected = child && childIsControlled ? child.props?.selected : child.props?.defaultSelected;
return childIsSelected ? child?.props.value : void 0;
}).filter((v) => v !== void 0);
return multiple ? selectedValues : selectedValues?.[0];
};
const HvSelectionList = React.forwardRef(function HvSelectionList2(props, ref) {
const {
id,
classes: classesProp,
className,
children,
name,
value: valueProp,
defaultValue,
required,
readOnly,
disabled,
label,
"aria-label": ariaLabel,
"aria-labelledby": ariaLabelledBy,
description,
"aria-describedby": ariaDescribedBy,
onChange,
status,
statusMessage,
"aria-errormessage": ariaErrorMessage,
orientation = "vertical",
multiple = false,
singleSelectionToggle = false,
...others
} = uikitReactUtils.useDefaultProps("HvSelectionList", props);
const { classes, cx } = SelectionList_styles.useClasses(classesProp);
const elementId = useUniqueId.useUniqueId(id);
const [value, setValue] = useControlled.useControlled(
valueProp,
defaultValue !== void 0 ? defaultValue : (
// when uncontrolled and no default value is given,
// extract the initial selected values from the children own state
() => getValueFromSelectedChildren(children, multiple)
)
);
const [validationState, setValidationState] = useControlled.useControlled(
status,
"standBy"
);
const [validationMessage] = useControlled.useControlled(statusMessage, "Required");
const [allValues, selectedState] = React.useMemo(() => {
const childValues = [];
const childSelectedState = [];
React.Children.toArray(children).forEach((child, i) => {
const childValue = child?.props?.value;
const childIsSelected = multiple ? value.indexOf(childValue) !== -1 : value === childValue;
childValues[i] = childValue;
childSelectedState[i] = childIsSelected;
});
return [childValues, childSelectedState];
}, [children, multiple, value]);
const selectionAnchor = React.useRef(void 0);
const listRef = React.useRef(null);
const listForkedRef = utils.useForkRef(ref, listRef);
React.useEffect(() => {
const handleMeta = (event) => {
const tempArray = [];
if (keyboardUtils.isKey(event, "ArrowUp") && event.shiftKey && listRef.current.contains(event.target) || keyboardUtils.isKey(event, "ArrowDown") && event.shiftKey && listRef.current.contains(event.target)) {
selectedState.forEach((isSelected, i) => {
if (i === event.target.value - 1) {
if (!isSelected) {
tempArray.push(allValues[i]);
}
} else if (isSelected) {
tempArray.push(allValues[i]);
}
});
setValue(tempArray);
}
};
window.addEventListener("keyup", handleMeta);
return () => {
window.removeEventListener("keyup", handleMeta);
};
}, [allValues, selectedState, setValue]);
const onChildChangeInterceptor = React.useCallback(
(index, childOnClick, evt) => {
childOnClick?.(evt);
if (!readOnly && !disabled) {
let newValue;
if (multiple) {
newValue = multiSelectionEventHandler.multiSelectionEventHandler(
evt,
index,
selectionAnchor,
allValues,
selectedState,
void 0
);
} else {
newValue = singleSelectionToggle && selectedState[index] ? null : allValues[index];
}
onChange?.(evt, newValue);
setValue(() => {
if (required && newValue.length === 0) {
setValidationState("invalid");
} else {
setValidationState("valid");
}
return newValue;
});
}
},
[
allValues,
disabled,
multiple,
onChange,
readOnly,
required,
selectedState,
setValidationState,
setValue,
singleSelectionToggle,
selectionAnchor
]
);
const modifiedChildren = React.useMemo(() => {
return React.Children.map(children, (child, i) => {
const childIsSelected = selectedState[i];
return React.cloneElement(child, {
role: "option",
selected: childIsSelected,
onClick: (evt) => onChildChangeInterceptor(i, child?.props?.onClick, evt),
disabled: disabled || child?.props?.disabled
});
});
}, [children, disabled, onChildChangeInterceptor, selectedState]);
const canShowError = ariaErrorMessage == null && (status !== void 0 && statusMessage !== void 0 || status === void 0 && required);
const errorMessageId = canShowError ? setId.setId(elementId, "error") : ariaErrorMessage;
const listId = label && setId.setId(elementId, "listbox") || "";
return /* @__PURE__ */ jsxRuntime.jsxs(
FormElement.HvFormElement,
{
id,
name,
status: validationState,
disabled,
required,
readOnly,
className: cx(classes.root, className),
children: [
label && /* @__PURE__ */ jsxRuntime.jsx(
Label.HvLabel,
{
showGutter: true,
id: setId.setId(elementId, "label"),
label,
className: classes.label
}
),
description && /* @__PURE__ */ jsxRuntime.jsx(
InfoMessage.HvInfoMessage,
{
id: setId.setId(elementId, "description"),
className: classes.description,
children: description
}
),
/* @__PURE__ */ jsxRuntime.jsx(
ListContainer.HvListContainer,
{
id: listId,
interactive: true,
condensed: true,
role: "listbox",
"aria-multiselectable": multiple || void 0,
"aria-label": ariaLabel,
"aria-labelledby": [label && setId.setId(elementId, "label"), ariaLabelledBy].join(" ").trim() || void 0,
"aria-invalid": validationState === "invalid" ? true : void 0,
"aria-errormessage": validationState === "invalid" ? errorMessageId : void 0,
"aria-describedby": [description && setId.setId(elementId, "description"), ariaDescribedBy].join(" ").trim() || void 0,
className: cx(classes.listbox, {
[classes.vertical]: orientation === "vertical",
[classes.horizontal]: orientation === "horizontal",
[classes.invalid]: validationState === "invalid"
}),
ref: listForkedRef,
...others,
children: modifiedChildren
}
),
canShowError && /* @__PURE__ */ jsxRuntime.jsx(
WarningText.HvWarningText,
{
id: setId.setId(elementId, "error"),
disableBorder: true,
className: classes.error,
children: validationMessage
}
)
]
}
);
});
exports.selectionListClasses = SelectionList_styles.staticClasses;
exports.HvSelectionList = HvSelectionList;