UNPKG

@adaptabletools/adaptable

Version:

Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

105 lines (104 loc) 7.37 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import * as React from 'react'; import SimpleButton from '../../../components/SimpleButton'; import { useAdaptable } from '../../AdaptableContext'; import { AdaptableIconComponent } from '../AdaptableIconComponent'; import { SingleSelect } from '../../../components/NewSelect'; import { FloatingFilterInputList } from './components/FloatingFilterInputList'; import { isPredicateEmpty, qlPredicateToString } from './utils'; import { AG_GRID_GROUPED_COLUMN } from '../../../Utilities/Constants/GeneralConstants'; import { Box, Flex } from '../../../components/Flex'; import { cn, getFocusableElements } from '../../../lib/utils'; import { Maximize2 } from 'lucide-react'; export const FloatingFilter = (props) => { const adaptable = useAdaptable(); const isMultiple = props.predicate?.args?.length > 1; const isManualApply = adaptable.api.filterApi.columnFilterApi.internalApi.shouldManuallyApplyColumnFilter(props.columnId); const isInlineEditable = !isMultiple && !isManualApply; let singleFilterPredicateDef = null; if (props.predicate.args.length === 1) { singleFilterPredicateDef = props.predicateDefs.find((predicateDef) => predicateDef.operator === props.predicate.args[0].operator); } const noInputs = !singleFilterPredicateDef?.inputs || singleFilterPredicateDef.inputs.length === 0; let showLabel = isMultiple || noInputs || isManualApply; if (props.columnId === AG_GRID_GROUPED_COLUMN) { showLabel = false; } let label = qlPredicateToString(props.predicate, props.predicateDefs); if (isManualApply && singleFilterPredicateDef && isPredicateEmpty(props.predicate.args[0], singleFilterPredicateDef)) { label = ''; } const showQuickFilterDropdown = adaptable.api.filterApi.columnFilterApi.internalApi.showQuickFilterDropdown(props.columnId); const colDef = adaptable.api.columnApi.getAGGridColDefForColumnId(props.columnId); const showExpandFilterButton = colDef?.suppressHeaderFilterButton !== true; const handleClear = () => props.onClear?.(); const [selectOpen, setSelectOpen] = React.useState(false); const currentOperator = props.predicate?.args[0]?.operator; const operatorOptions = props.predicateDefs.map((predicateDef) => ({ label: (_jsxs(Box, { className: "twa:flex twa:items-center", children: [_jsx(Box, { className: "twa:mr-2 twa:flex twa:items-center", children: predicateDef.icon }), _jsx(Box, { className: "twa:truncate", "data-name": "filter-predicate-label", "data-label": predicateDef.label, children: predicateDef.label })] })), tooltip: predicateDef.label, ariaLabel: predicateDef.label, value: predicateDef.operator, })); const renderTriggerValue = () => (_jsxs(Flex, { alignItems: "center", className: "twa:min-w-0", children: [_jsx(Box, { className: "twa:flex twa:items-center", children: !isManualApply && singleFilterPredicateDef?.icon ? (singleFilterPredicateDef?.icon) : (_jsx(AdaptableIconComponent, { icon: { name: 'filter' } })) }), showLabel && (_jsx(Box, { className: "ab-FloatingFilter-label twa:ml-2 twa:flex-1 twa:truncate", title: label, children: label }))] })); let filterDropdown = null; const filterDropdownSelect = (_jsx("div", { className: cn('twa:flex twa:box-border twa:self-stretch twa:min-h-0 twa:h-full twa:py-0.5 twa:px-0.5', !isInlineEditable && 'twa:min-w-0 twa:flex-1'), children: _jsx(SingleSelect, { chevronIcon: null, "data-name": "floating-filter-button", ariaLabel: `Column Filter Operator Dropdown: current operator is ${label}`, stopMouseDownPropagation: true, disabled: props.disabled, open: selectOpen, extraWidthChars: 5, onOpenChange: (nextOpen) => { if (nextOpen && !isInlineEditable) { adaptable.api.filterApi.columnFilterApi.internalApi.openColumnFilterPopup(props.columnId); return; } setSelectOpen(nextOpen); }, value: currentOperator, placeholder: label, items: operatorOptions, showItemTooltip: true, renderValue: renderTriggerValue, onValueChange: (operator) => { props.onPredicateChange({ operator: props.predicate.operator, args: [{ operator: operator, args: [] }], }); }, className: cn('twa:h-full twa:w-full twa:min-h-0 twa:text-left twa:px-0.5 twa:py-0.5 twa:border-none', 'twa:shadow-none twa:cursor-pointer', 'twa:text-primary-foreground twa:hover:bg-current/15') }) })); if (isInlineEditable) { filterDropdown = showQuickFilterDropdown && filterDropdownSelect; } else { filterDropdown = filterDropdownSelect; } const showClearButton = isMultiple || !isPredicateEmpty(props.predicate.args[0], singleFilterPredicateDef); return (_jsxs(Flex, { className: "ab-FloatingFilter twa:w-full", onKeyDownCapture: (e) => { if (e.key !== 'Tab') { return; } const wrapper = e.currentTarget; const focusable = getFocusableElements(wrapper); if (focusable.length === 0) { return; } const active = document.activeElement; const currentIndex = active ? focusable.indexOf(active) : -1; if (currentIndex === -1) { return; } const nextIndex = currentIndex + (e.shiftKey ? -1 : 1); if (nextIndex < 0 || nextIndex >= focusable.length) { return; } e.preventDefault(); e.nativeEvent.stopImmediatePropagation(); focusable[nextIndex]?.focus(); requestAnimationFrame(() => { if (document.activeElement === document.body || document.activeElement === null) { const refreshed = getFocusableElements(wrapper); refreshed[Math.min(nextIndex, refreshed.length - 1)]?.focus(); } }); }, children: [filterDropdown, isInlineEditable && (_jsx(Flex, { className: "twa:flex-1 twa:min-w-0 twa:min-h-0 twa:h-full", children: _jsx(FloatingFilterInputList, { onKeyDown: props.onKeydown, columnId: props.columnId, disabled: props.disabled, predicate: props.predicate.args[0], predicateDefs: props.predicateDefs, onPredicateChange: (predicate) => { props.onPredicateChange({ operator: props.predicate.operator, args: [predicate], }); } }) })), isInlineEditable && showExpandFilterButton && (_jsx(SimpleButton, { className: cn('twa:px-1 twa:my-0.5', !showClearButton && 'twa:mr-0.5'), "aria-label": "Expand filter", tooltip: "Open filter popup", onClick: () => { adaptable.api.filterApi.columnFilterApi.internalApi.openColumnFilterPopup(props.columnId, { onChange: props.onChange, }); }, "data-name": "expand-filter", icon: _jsx(Maximize2, { size: 20, strokeWidth: 1.5 }), variant: "text" })), showClearButton && (_jsx(SimpleButton, { "data-name": "clear-filter", className: "twa:p-0 twa:my-0.5 twa:mr-0.5", variant: "text", onClick: handleClear, icon: "close", tooltip: "Clear filter" }))] })); };