UNPKG

@wix/design-system

Version:

@wix/design-system

152 lines 7.96 kB
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