import React, { useContext, useEffect, useRef, useState } from 'react' import { ColumnInstance } from 'react-table' import classnames from 'classnames' import { addListener, removeListener } from 'resize-detector' import Dropdown, { DropdownRef } from '../../../Dropdown' import { PopupContainerProvider } from '../../../PopupContainerProvider' import { concat } from '../../../utils' import { HeaderContext } from '../../Header' import DefaultFilter, { Icon } from '../SelectFilter' import { TableColumnFilterOptions, TableColumnMultiSelectFilterOptions, TableColumnSelectFilterOptions } from '../../types' export default function FilterIcon({ column }: { column: ColumnInstance }) { const { headerElement, headerPrefix } = useContext(HeaderContext) const prefix = concat(headerPrefix, 'filter') const filteredCls = concat(prefix, 'filtered') const disabledCls = concat(prefix, 'disabled') const ref = useRef(null) const [offset, setOffset] = useState([0, 0]) const [dropdownVisible, setDropdownVisible] = useState(false) const dropdownRef = useRef(null) const filterOptions: TableColumnFilterOptions = column.meta.filter! useEffect(() => { const iconWrapper = ref.current if (iconWrapper && headerElement) { const handDomChange = () => { const offsetX = headerElement.getBoundingClientRect().left - iconWrapper.getBoundingClientRect().left const offsetY = headerElement.getBoundingClientRect().bottom - iconWrapper.getBoundingClientRect().bottom setOffset([offsetX, offsetY]) } handDomChange() // icon 本身位置也可能发生变化,比如被排序 icon 挤开 addListener(iconWrapper, handDomChange) addListener(headerElement, handDomChange) return () => { removeListener(iconWrapper, handDomChange) removeListener(headerElement, handDomChange) } } }, [headerElement]) // TODO 确认下 Dropdown 的 popup 为什么传了新的 align.offset 属性不刷新自己的位置的问题 // 上面代码 setOffset 之后,dropdown 弹窗位置不刷新,这里强制刷新对齐下 useEffect(() => dropdownRef.current?.forcePopupAlign(), [offset]) // TODO 支持 Search const overlay = ( setDropdownVisible(false)} visible={dropdownVisible} /> ) const className = classnames( prefix, (dropdownVisible || !isFilterValueEmpty(filterOptions.value)) && filteredCls, filterOptions.optionItems.length === 0 && disabledCls ) return ( // 实现 icon 高亮的时候,考虑把 th 作为 container
) } function isFilterValueEmpty(value: TableColumnMultiSelectFilterOptions['value'] | TableColumnSelectFilterOptions['value']) { if (Array.isArray(value)) { return value.length === 0 } return value == null }