@hitachivantara/uikit-react-core
Version:
Core React components for the NEXT Design System.
252 lines (251 loc) • 8.85 kB
JavaScript
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const jsxRuntime = require("react/jsx-runtime");
const React = require("react");
const reactWindow = require("react-window");
const uikitReactUtils = require("@hitachivantara/uikit-react-utils");
const icons = require("../icons.cjs");
const CounterLabel = require("../utils/CounterLabel.cjs");
const setId = require("../utils/setId.cjs");
const List_styles = require("./List.styles.cjs");
const useSelectableList = require("./useSelectableList.cjs");
const utils = require("./utils.cjs");
const CheckBox = require("../CheckBox/CheckBox.cjs");
const Radio = require("../Radio/Radio.cjs");
const OverflowTooltip = require("../OverflowTooltip/OverflowTooltip.cjs");
const Link = require("../Link/Link.cjs");
const ListContainer = require("../ListContainer/ListContainer.cjs");
const ListItem = require("../ListContainer/ListItem/ListItem.cjs");
const DEFAULT_LABELS = {
/** The label used for the All checkbox action. @deprecated no longer used */
selectAll: "Select All",
/** The label used in the middle of the multi-selection count. */
selectionConjunction: "/"
};
const HvList = (props) => {
const {
id,
classes: classesProp,
className,
multiSelect = false,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
hasTooltips = false,
showSelectAll = false,
labels = DEFAULT_LABELS,
useSelector = false,
selectable = true,
singleSelectionToggle = true,
condensed = false,
onChange,
onClick,
values: valuesProp = [],
height,
virtualized = false,
...others
} = uikitReactUtils.useDefaultProps("HvList", props);
const { classes, cx } = List_styles.useClasses(classesProp);
const [list, setList, selection] = useSelectableList.useSelectableList(valuesProp);
const listRef = React.useRef(null);
React.useEffect(() => {
const passedProps = { multiSelect, selectable, singleSelectionToggle };
const parsedList = utils.parseList(
void 0,
passedProps,
void 0,
valuesProp
);
setList(parsedList);
}, [valuesProp, multiSelect, selectable, singleSelectionToggle, setList]);
const [role, itemRole] = React.useMemo(() => {
if (selectable && useSelector) return ["list", "listitem"];
if (selectable) return ["listbox", "option"];
return ["menu", "menuitem"];
}, [selectable, useSelector]);
const handleSelect = (evt, item) => {
if (!item.path) evt.preventDefault();
if (item.disabled) return;
const passedProps = { multiSelect, selectable, singleSelectionToggle };
const parsedList = utils.parseList(item, passedProps, void 0, list);
setList(parsedList);
onClick?.(evt, item);
onChange?.(parsedList);
};
const handleSelectAll = () => {
const passedProps = { multiSelect, selectable, singleSelectionToggle };
const anySelectableSelected = list.some(
(elem) => elem.selected || elem.disabled
);
const parsedList = utils.parseList(
void 0,
passedProps,
!anySelectableSelected,
list
);
setList(parsedList);
onChange?.(parsedList);
};
const renderLeftIcon = (item) => {
return React.isValidElement(item.icon) ? item.icon : typeof item.icon === "function" ? item.icon?.({
isSelected: item.selected,
isDisabled: item.disabled
}) : null;
};
const renderSelectAll = () => {
const anySelected2 = !!selection?.length;
const allSelected = selection.length === list.length;
return /* @__PURE__ */ jsxRuntime.jsx(
CheckBox.HvCheckBox,
{
id: setId.setId(id, "select-all"),
label: /* @__PURE__ */ jsxRuntime.jsx(
CounterLabel.CounterLabel,
{
selected: selection.length,
total: list.length,
conjunctionLabel: labels.selectionConjunction
}
),
onChange: handleSelectAll,
className: classes.selectAllSelector,
indeterminate: anySelected2 && !allSelected,
checked: allSelected
}
);
};
const renderItemText = (item) => {
return !multiSelect && item.path ? /* @__PURE__ */ jsxRuntime.jsx(Link.HvLink, { route: item.path, classes: { a: classes.link }, children: /* @__PURE__ */ jsxRuntime.jsx(OverflowTooltip.HvOverflowTooltip, { data: item.label }) }) : /* @__PURE__ */ jsxRuntime.jsx(OverflowTooltip.HvOverflowTooltip, { data: item.label });
};
const renderSelectItem = (item, itemId) => {
if (!useSelector) return renderItemText(item);
const Component = multiSelect ? CheckBox.HvCheckBox : Radio.HvRadio;
return /* @__PURE__ */ jsxRuntime.jsx(
Component,
{
id: setId.setId(itemId, "selector"),
label: /* @__PURE__ */ jsxRuntime.jsx(OverflowTooltip.HvOverflowTooltip, { data: item.label }),
checked: item.selected || false,
disabled: item.disabled,
onChange: multiSelect ? (evt) => handleSelect(evt, item) : void 0,
classes: {
root: classes.selectorRoot,
container: classes.selectorContainer,
label: classes.truncate
}
}
);
};
const renderListItem = (item, i, otherProps = {}) => {
const itemId = setId.setId(id, "item", i);
const selected = item.selected || false;
const startAdornment = !useSelector && item.icon ? renderLeftIcon(item) : null;
return /* @__PURE__ */ jsxRuntime.jsx(
ListItem.HvListItem,
{
id: itemId,
role: itemRole,
disabled: item.disabled || void 0,
className: classes.item,
classes: {
selected: cx({
[classes.itemSelector]: useSelector || multiSelect
})
},
selected: multiSelect || selected ? selected : void 0,
onClick: (evt) => handleSelect(evt, item),
startAdornment,
endAdornment: item.showNavIcon && /* @__PURE__ */ jsxRuntime.jsx(icons.HvIcon, { name: "CaretRight", className: classes.box, size: "xs" }),
...otherProps,
children: renderSelectItem(item, itemId)
},
i
);
};
const filteredList = list.filter((it) => !it.isHidden);
const anySelected = list.map((item) => item.selected && !item.disabled).reduce((result, selected) => result || selected, false);
const selectedItemIndex = list.findIndex((item) => item.selected);
React.useEffect(() => {
if (selectedItemIndex >= 0 && listRef.current !== null) {
listRef.current.scrollToItem(selectedItemIndex);
}
}, [listRef, selectedItemIndex]);
const renderVirtualizedListItem = ({
index,
style
}) => {
const item = filteredList[index];
const tabIndex = item.tabIndex || !anySelected && index === 0 || item.selected && !item.disabled ? 0 : -1;
return renderListItem(item, index, {
style: {
...style,
top: `${parseFloat(style.top) + 5}px`,
left: `${parseFloat(style.left) + 5}px`,
width: `calc(${parseFloat(style.width)}% - 10px)`
},
tabIndex,
interactive: true,
condensed,
disableGutters: useSelector
});
};
const ariaMultiSelectable = role === "listbox" && multiSelect || void 0;
const ListContainer$1 = React.useMemo(() => {
return React.forwardRef(
({ ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
ListContainer.HvListContainer,
{
id,
className: cx(classes.root, className),
role,
interactive: true,
condensed,
disableGutters: useSelector,
"aria-multiselectable": ariaMultiSelectable,
ref,
...rest
}
)
);
}, [
cx,
id,
useSelector,
className,
classes.root,
role,
condensed,
ariaMultiSelectable
]);
if (filteredList.length === 0) return null;
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
multiSelect && useSelector && showSelectAll && renderSelectAll(),
!virtualized ? /* @__PURE__ */ jsxRuntime.jsx(
ListContainer.HvListContainer,
{
id,
className: cx(classes.root, className),
role,
interactive: true,
condensed,
disableGutters: useSelector,
"aria-multiselectable": ariaMultiSelectable,
...others,
children: filteredList.map((item, i) => renderListItem(item, i))
}
) : /* @__PURE__ */ jsxRuntime.jsx(
reactWindow.FixedSizeList,
{
ref: listRef,
className: classes.virtualizedRoot,
height: (height || 0) + 5,
width: "100%",
itemCount: filteredList.length,
itemSize: condensed ? 32 : 40,
innerElementType: ListContainer$1,
...others,
children: renderVirtualizedListItem
}
)
] });
};
exports.listClasses = List_styles.staticClasses;
exports.HvList = HvList;