@wix/design-system
Version:
@wix/design-system
152 lines • 7.96 kB
JavaScript
import React, { forwardRef, useRef } from 'react';
import PropTypes from 'prop-types';
import { DATA_HOOKS, ALIGN, PADDING, DRAG_HANDLE_SIZE, } from './TableListItem.constants';
import { st, classes } from './TableListItem.st.css.js';
import Checkbox from '../Checkbox';
import { DragHandle } from '../DragHandle/DragHandle';
import { forkRef } from '../utils/forkRef';
import { useDraggableContainer } from '../DraggableContainer/useDraggableContainer';
import { CaretRight } from '@wix/wix-ui-icons-common/system';
const getWidthStyle = (options) => options.reduce((acc, { width }) => `${acc} ${typeof width === 'number' ? width + 'px' : width || '1fr'}`, '');
const TableListItem = forwardRef(({ options, verticalPadding = PADDING.small, horizontalPadding = PADDING.large, selectable = false, checkbox = false, checkboxDisabled, checkboxTooltipContent, checkboxTooltipProps, checked, onCheckboxChange = () => { }, focused, onBlur, showDivider = false, onKeyUp, onClick, onMouseEnter, onMouseLeave, className, dataHook, draggable = false, dragging, dragDisabled, dragHandleProps, hideDragHandle, dragHandleSize = 'large', showDragHandleOnHover = false, border = false, showSelectionBorder = true, expandable = false, expandDisabled, reserveExpandHandleSpace, reserveDragHandleSpace, onClickExpand, expanded = false, ariaLabel, }, ref) => {
const draggableRef = useRef(null);
const rootRef = useRef(null);
const hasControls = draggable ||
expandable ||
checkbox ||
reserveExpandHandleSpace ||
reserveDragHandleSpace;
const isSelectableWithoutCheckbox = !!(selectable && onClick && !checkbox);
const noVisibleControls = hideDragHandle &&
!expandable &&
!checkbox &&
!reserveExpandHandleSpace &&
!reserveDragHandleSpace;
React.useEffect(() => {
if (draggableRef.current && focused) {
draggableRef.current.focus();
}
}, [draggableRef, focused]);
React.useImperativeHandle(ref, () => ({
focus: () => rootRef.current && rootRef.current.focus(),
}));
const { className: draggableContainerClassName } = useDraggableContainer({
dragging,
draggable,
dragDisabled,
highlight: true,
});
function selectItem(e) {
if (e.key === 'Enter' && document.activeElement === rootRef?.current) {
onClick?.(e);
}
}
function interceptOnClickExpand(e) {
onClickExpand?.(e);
e.stopPropagation();
}
const ExpandHandle = ({ children }) => {
if (expandable) {
return (React.createElement("div", { className: st(classes.expandHandle, {
expandable: expandable && !expandDisabled,
}), onClick: expandDisabled ? undefined : interceptOnClickExpand, "data-hook": DATA_HOOKS.tableListItemExpandHandleContainer }, children));
}
if (reserveExpandHandleSpace) {
return (React.createElement("div", { className: st(classes.expandHandle, {
hidden: reserveExpandHandleSpace,
}) }, children));
}
return null;
};
return (React.createElement("div", { ref: rootRef, "data-hook": dataHook, className: st(classes.root, {
draggable: draggable && !dragDisabled,
dragDisabled,
dragging,
showDragHandleOnHover,
checked: (checkbox || selectable) && checked,
showDivider,
clickable: !!onClick,
selectable: isSelectableWithoutCheckbox,
verticalPadding,
horizontalPadding,
border,
showSelectionBorder,
dragHandleSize,
hideDragHandle,
noVisibleControls,
}, className, draggableContainerClassName), tabIndex: !isSelectableWithoutCheckbox ? -1 : 0, "aria-label": !isSelectableWithoutCheckbox ? undefined : ariaLabel, "aria-selected": !isSelectableWithoutCheckbox ? undefined : checked, onKeyDown: !isSelectableWithoutCheckbox ? undefined : e => selectItem(e), onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onClick: onClick },
hasControls && (React.createElement("div", { className: st(classes.controlsContainer, { dragHandleSize }) },
draggable ? (React.createElement("div", { className: classes.handleContainer },
React.createElement(DragHandle, { tabIndex: onKeyUp ? 0 : undefined, ...dragHandleProps, domRef: forkRef(draggableRef, dragHandleProps?.domRef || null), onBlur: onBlur, onKeyUp: onKeyUp, dragging: dragging, disabled: dragDisabled, dataHook: DATA_HOOKS.tableListItemDragHandle, dragHandleSize: dragHandleSize }))) : reserveDragHandleSpace ? (React.createElement("div", { className: st(classes.handleContainer, {
hidden: reserveDragHandleSpace,
}) },
React.createElement(DragHandle, { dragHandleSize: dragHandleSize }))) : null,
React.createElement(ExpandHandle, null,
React.createElement(CaretRight, { className: st(classes.caretIcon, { expanded }) })),
checkbox && (React.createElement("div", { className: st(classes.checkbox, { checkboxDisabled }), "data-hook": DATA_HOOKS.tableListItemCheckboxContainer },
React.createElement(Checkbox, { checked: checked, disabled: checkboxDisabled, onChange: checkboxDisabled ? undefined : onCheckboxChange, dataHook: DATA_HOOKS.tableListItemCheckbox, tooltipContent: checkboxTooltipContent, tooltipProps: checkboxTooltipProps }))))),
React.createElement("div", { className: classes.optionsContainer, style: {
gridTemplateColumns: getWidthStyle(options),
}, "data-hook": DATA_HOOKS.tableListItemOptionsContainer }, options.map(({ value, align }, index) => (React.createElement("div", { className: st(classes.align, {
position: align && ALIGN[align],
}), key: index, "data-hook": DATA_HOOKS.tableListItemValue }, value))))));
});
TableListItem.displayName = 'TableListItem';
TableListItem.propTypes = {
dataHook: PropTypes.string,
className: PropTypes.string,
// @ts-expect-error incompatibility https://github.com/DefinitelyTyped/DefinitelyTyped/issues/45094
options: PropTypes.arrayOf(PropTypes.shape({
value: PropTypes.node.isRequired,
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
align: PropTypes.oneOf([ALIGN.left, ALIGN.center, ALIGN.right]),
}).isRequired).isRequired,
verticalPadding: PropTypes.oneOf([
PADDING.large,
PADDING.medium,
PADDING.small,
PADDING.tiny,
PADDING.xTiny,
PADDING.xxTiny,
]),
horizontalPadding: PropTypes.oneOf([
PADDING.large,
PADDING.medium,
PADDING.small,
PADDING.tiny,
PADDING.xTiny,
PADDING.xxTiny,
]),
dragging: PropTypes.bool,
checkbox: PropTypes.bool,
checkboxDisabled: PropTypes.bool,
checked: PropTypes.bool,
onCheckboxChange: PropTypes.func,
draggable: PropTypes.bool,
dragDisabled: PropTypes.bool,
showDragHandleOnHover: PropTypes.bool,
showDivider: PropTypes.bool,
onBlur: PropTypes.func,
onKeyUp: PropTypes.func,
focused: PropTypes.bool,
onClick: PropTypes.func,
onMouseEnter: PropTypes.func,
onMouseLeave: PropTypes.func,
dragHandleProps: PropTypes.object,
checkboxTooltipContent: PropTypes.any,
checkboxTooltipProps: PropTypes.object,
border: PropTypes.bool,
showSelectionBorder: PropTypes.bool,
dragHandleSize: PropTypes.oneOf([
DRAG_HANDLE_SIZE.small,
DRAG_HANDLE_SIZE.large,
]),
expandable: PropTypes.bool,
expanded: PropTypes.bool,
onClickExpand: PropTypes.func,
expandDisabled: PropTypes.bool,
selectable: PropTypes.bool,
ariaLabel: PropTypes.string,
};
export default TableListItem;
//# sourceMappingURL=TableListItem.js.map