@ui5/webcomponents-react
Version:
React Wrapper for UI5 Web Components and additional components
272 lines (270 loc) • 10.8 kB
JavaScript
'use client';
import BusyIndicatorSize from '@ui5/webcomponents/dist/types/BusyIndicatorSize.js';
import ButtonDesign from '@ui5/webcomponents/dist/types/ButtonDesign.js';
import { isMac as isMacFn } from '@ui5/webcomponents-base/dist/Device.js';
import circleTask2Icon from '@ui5/webcomponents-icons/dist/circle-task-2.js';
import moveToTopIcon from '@ui5/webcomponents-icons/dist/collapse-group.js';
import moveToBottomIcon from '@ui5/webcomponents-icons/dist/expand-group.js';
import moveDownIcon from '@ui5/webcomponents-icons/dist/navigation-down-arrow.js';
import moveUpIcon from '@ui5/webcomponents-icons/dist/navigation-up-arrow.js';
import { useI18nBundle, useStylesheet } from '@ui5/webcomponents-react-base';
import { clsx } from 'clsx';
import { forwardRef, useContext, useEffect, useMemo, useRef, useState } from 'react';
import { FlexBoxAlignItems } from '../../enums/FlexBoxAlignItems.js';
import { FlexBoxDirection } from '../../enums/FlexBoxDirection.js';
import { FlexBoxJustifyContent } from '../../enums/FlexBoxJustifyContent.js';
import { DOWN_ARROW, FILTER_DIALOG_REORDER_FILTERS, FILTER_IS_ACTIVE, MOVE_DOWN, MOVE_TO_BOTTOM, MOVE_TO_TOP, MOVE_UP, UP_ARROW } from '../../i18n/i18n-defaults.js';
import { FilterBarDialogContext } from '../../internal/FilterBarDialogContext.js';
import { BusyIndicator } from '../../webComponents/BusyIndicator/index.js';
import { Button } from '../../webComponents/Button/index.js';
import { Icon } from '../../webComponents/Icon/index.js';
import { Label } from '../../webComponents/Label/index.js';
import { TableCell } from '../../webComponents/TableCell/index.js';
import { TableRow } from '../../webComponents/TableRow/index.js';
import { FlexBox } from '../FlexBox/index.js';
import { classNames, styleData } from './FilterGroupItem.module.css.js';
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
const isMac = isMacFn();
/**
* Represents a filter belonging to the `FilterBar`.
*/
const FilterGroupItem = /*#__PURE__*/forwardRef((props, ref) => {
useStylesheet(styleData, FilterGroupItem.displayName);
const {
groupName = 'default',
considerGroupName,
label = '',
labelTooltip,
required,
hidden,
hiddenInFilterBar,
children,
loading,
className,
slot,
active,
filterKey,
...rest
} = props;
const i18nBundle = useI18nBundle('@ui5/webcomponents-react');
const index = props['data-index'];
const filtersCount = props['data-filters-count'];
const isomporphicReorderKey = isMac ? 'CMD' : 'CTRL';
const tableRowRef = useRef(null);
const {
isFilterInDialog,
isListView,
withValues,
enableReordering,
showBtnsOnHover,
currentReorderedItemOrderId,
handleFocusFallback,
onReorder,
setShowBtnsOnHover,
setSelectedKeys,
setRequiredKeys,
prevIsListView
} = useContext(FilterBarDialogContext);
const listViewHasChanged = useRef(prevIsListView?.current !== isListView);
useEffect(() => {
if (prevIsListView?.current !== isListView) {
listViewHasChanged.current = true;
}
}, [isListView, prevIsListView]);
const inFB = !isFilterInDialog;
const withReordering = enableReordering && !withValues && isListView;
const initialPosition = useMemo(() => {
if (index === 0) {
return 'first';
}
if (index === filtersCount - 1) {
return 'last';
}
return undefined;
}, [index, filtersCount]);
const [itemPosition, setItemPosition] = useState(initialPosition);
useEffect(() => {
setItemPosition(initialPosition);
}, [initialPosition]);
const handleFocus = e => {
setShowBtnsOnHover(false);
if (e.currentTarget.nextSibling === null) {
setItemPosition('last');
} else if (index === 0) {
setItemPosition('first');
} else {
setItemPosition(undefined);
}
};
const handleReorder = e => {
setItemPosition(undefined);
onReorder({
index,
direction: e.currentTarget.dataset.reorder,
target: tableRowRef.current,
filterKey
});
};
const handleKeyDown = e => {
if (e.ctrlKey || e.metaKey) {
const directionMap = {
Home: 'top',
End: 'bottom',
ArrowUp: 'up',
ArrowDown: 'down'
};
const direction = directionMap[e.key];
if (direction) {
setItemPosition(undefined);
onReorder({
index,
direction,
target: e.currentTarget,
filterKey
});
}
}
};
useEffect(() => {
if (withReordering && tableRowRef.current && currentReorderedItemOrderId === filterKey && typeof index === 'number') {
handleFocusFallback();
}
}, [withReordering, currentReorderedItemOrderId, filterKey, index]);
useEffect(() => {
if (!inFB && !hidden && !listViewHasChanged?.current) {
if (setSelectedKeys) {
setSelectedKeys(prev => {
const keysSet = new Set(prev);
if (hiddenInFilterBar && !required) {
keysSet.delete(`${filterKey}`);
} else {
keysSet.add(`${filterKey}`);
}
return Array.from(keysSet);
});
}
if (setRequiredKeys) {
setRequiredKeys(prev => ({
...prev,
[`${filterKey}`]: !!required
}));
}
}
if (listViewHasChanged?.current) {
listViewHasChanged.current = false;
}
}, [inFB, hidden, hiddenInFilterBar, filterKey, setSelectedKeys, isListView, required, setRequiredKeys]);
if (!required && (hidden || inFB && hiddenInFilterBar)) return null;
if (!inFB) {
return (
/*#__PURE__*/
//todo: disable selection for required fields when it's possible, or the table is fully controllable (https://github.com/UI5/webcomponents/issues/5662)
_jsxs(TableRow, {
ref: tableRowRef,
rowKey: `${filterKey}`,
"data-text": label,
"data-required": required,
"data-component-name": "FilterBarDialogTableRow",
className: clsx(classNames.dialogTableRow, withReordering && classNames.withReorderBtns, withReordering && showBtnsOnHover && classNames.withReorderHoverBtns),
onFocus: withReordering ? handleFocus : undefined,
onKeyDown: withReordering ? handleKeyDown : undefined,
"aria-live": withReordering ? 'polite' : undefined,
"aria-label": withReordering ? i18nBundle.getText(FILTER_DIALOG_REORDER_FILTERS, isomporphicReorderKey) : undefined,
children: [/*#__PURE__*/_jsx(TableCell, {
"data-component-name": "FilterBarDialogTableCellFilter",
children: /*#__PURE__*/_jsxs(FlexBox, {
fitContainer: true,
direction: FlexBoxDirection.Column,
justifyContent: FlexBoxJustifyContent.Center,
className: classNames.labelContainer,
"data-in-filters-dialog": true,
children: [/*#__PURE__*/_jsx(Label, {
className: classNames.dialogCellLabel,
title: labelTooltip ?? label,
required: required,
showColon: !!label && withValues,
children: label
}), withValues && children]
})
}), !withValues && /*#__PURE__*/_jsxs(TableCell, {
className: classNames.dialogActiveCell,
"data-component-name": "FilterBarDialogTableCellActive",
children: [isListView && withReordering && /*#__PURE__*/_jsxs(FlexBox, {
fitContainer: true,
justifyContent: FlexBoxJustifyContent.Center,
alignItems: FlexBoxAlignItems.Center,
className: classNames.reorderBtnsContainer,
"data-component-name": "FilterBarDialogTableCellReorderBtns",
children: [/*#__PURE__*/_jsx(Button, {
onClick: handleReorder,
design: ButtonDesign.Transparent,
icon: moveToTopIcon,
"data-reorder": "top",
disabled: itemPosition === 'first',
tooltip: `${i18nBundle.getText(MOVE_TO_TOP, ` (${isomporphicReorderKey}+Home)`)})`,
"data-component-name": "FilterBarDialogReorderBtnTop"
}), /*#__PURE__*/_jsx(Button, {
onClick: handleReorder,
design: ButtonDesign.Transparent,
icon: moveUpIcon,
"data-reorder": "up",
disabled: itemPosition === 'first',
tooltip: `${i18nBundle.getText(MOVE_UP, ` (${isomporphicReorderKey}+${i18nBundle.getText(UP_ARROW)})`)}`,
"data-component-name": "FilterBarDialogReorderBtnUp"
}), /*#__PURE__*/_jsx(Button, {
onClick: handleReorder,
design: ButtonDesign.Transparent,
icon: moveDownIcon,
"data-reorder": "down",
disabled: itemPosition === 'last',
tooltip: `${i18nBundle.getText(MOVE_DOWN, ` (${isomporphicReorderKey}+${i18nBundle.getText(DOWN_ARROW)})`)}`,
"data-component-name": "FilterBarDialogReorderBtnDown"
}), /*#__PURE__*/_jsx(Button, {
onClick: handleReorder,
design: ButtonDesign.Transparent,
icon: moveToBottomIcon,
"data-reorder": "bottom",
disabled: itemPosition === 'last',
tooltip: `${i18nBundle.getText(MOVE_TO_BOTTOM, ` (${isomporphicReorderKey}+End`)})`,
"data-component-name": "FilterBarDialogReorderBtnBottom"
})]
}), active && /*#__PURE__*/_jsxs(_Fragment, {
children: [/*#__PURE__*/_jsx(Icon, {
name: circleTask2Icon,
className: classNames.dialogActiveIcon,
"aria-hidden": "true"
}), /*#__PURE__*/_jsx("span", {
className: classNames.pseudoInvisibleText,
children: i18nBundle.getText(FILTER_IS_ACTIVE)
})]
})]
})]
})
);
}
const labelWithGroupName = considerGroupName && groupName !== 'default' ? `${label} (${groupName})` : label;
return /*#__PURE__*/_jsx("div", {
ref: ref,
slot: slot,
...rest,
className: clsx(classNames.filterItem, className),
children: /*#__PURE__*/_jsxs("div", {
className: classNames.innerFilterItemContainer,
"data-in-filter-bar": true,
children: [/*#__PURE__*/_jsx(FlexBox, {
children: /*#__PURE__*/_jsx(Label, {
title: labelTooltip ?? label,
required: required,
showColon: !!label,
children: labelWithGroupName
})
}), loading ? /*#__PURE__*/_jsx(BusyIndicator, {
className: classNames.loadingContainer,
active: true,
size: BusyIndicatorSize.S
}) : children]
})
});
});
FilterGroupItem.displayName = 'FilterGroupItem';
export { FilterGroupItem };