UNPKG

@hitachivantara/uikit-react-core

Version:

Core React components for the NEXT Design System.

252 lines (251 loc) 8.85 kB
"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;