import { useIntl } from '@umijs/max'; import type { SelectProps } from 'antd'; import { Checkbox, Tag } from 'antd'; import { CheckboxChangeEvent } from 'antd/es/checkbox'; import React, { forwardRef, useEffect, useImperativeHandle } from 'react'; import styled from 'styled-components'; import AutoTooltip from '../auto-tooltip'; import BaseSelect from './base/select'; const OptionWrapper = styled.div` display: flex; align-items: center; gap: 8px; `; const DropdownWrapper = styled.div` .ant-select-item { padding-inline-start: 8px; &:hover { background-color: var(--ant-select-option-active-bg); } } .ant-select-item-option-selected:not(.ant-select-item-option-disabled) { background-color: unset; font-weight: unset; &:hover { background-color: var(--ant-select-option-active-bg); } } `; const SelectAllWrapper = styled.div` margin-bottom: 10px; padding: 5px 8px; font-size: 12px; border-bottom: 1px solid var(--ant-color-split); .ant-checkbox-wrapper { color: var(--ant-color-text-tertiary); } `; const TagWrapper = styled(Tag)` border-radius: 12px; `; const SimpleSelect: React.FC = forwardRef((props, ref) => { const intl = useIntl(); const { options = [], showTags, ...restProps } = props; const [allSelection, setAllSelection] = React.useState<{ checked: boolean; indeterminate: boolean; }>({ checked: false, indeterminate: false }); const [optionsList, setOptionsList] = React.useState(options || []); const selectRef = React.useRef(null); const selectorRef = React.useRef(null); useEffect(() => { setOptionsList(options || []); }, [options]); const optionRender = (option: any, info: any) => { const { value, label } = option; return ( {restProps.value?.includes?.(value) ? ( ) : ( )} {label} ); }; const handleOnCheckboxChange = (e: CheckboxChangeEvent) => { const isChecked = e.target.checked; const allValues = optionsList?.map((opt: any) => opt.value) || []; setAllSelection({ checked: isChecked, indeterminate: false }); let allSelectedValues = [...(restProps.value || [])]; if (isChecked) { // Select all options allSelectedValues = Array.from( new Set([...allSelectedValues, ...allValues]) ); } else { // Deselect all options allSelectedValues = allSelectedValues.filter( (value) => !allValues.includes(value) ); } restProps.onChange?.(allSelectedValues, optionsList || []); }; const dropdownRender = (originPanel: React.ReactNode) => { return ( {restProps.mode === 'multiple' && ( {intl.formatMessage({ id: 'common.checkbox.all' })} )} {originPanel} ); }; const handleOnChange = (value: any, option: any) => { const selectedValues = Array.isArray(value) ? value : [value]; const allSelected = optionsList?.map((opt: any) => opt.value) || []; const isAllSelected = selectedValues.length === allSelected?.length; setAllSelection({ checked: isAllSelected, indeterminate: !isAllSelected && selectedValues.length > 0 }); restProps.onChange?.(selectedValues, option); }; const filterOption = (inputValue: string, option: any) => { if (!option || !option.label) return false; return option.label.toLowerCase().includes(inputValue.toLowerCase()); }; const checkAllSelection = (list: Global.BaseOption[]) => { if ( !restProps.value || !Array.isArray(restProps.value) || list.length === 0 ) { setAllSelection({ checked: false, indeterminate: false }); return; } const selectedValues = new Set(restProps.value); const allValues = list?.map((opt: any) => opt.value) || []; const isAllSelected = allValues.every((val: any) => selectedValues.has(val) ); const isSomeSelected = allValues.some((val: any) => selectedValues.has(val) ); setAllSelection({ checked: isAllSelected, indeterminate: isSomeSelected && !isAllSelected }); }; const TagRender = (props: any) => { const { label } = props; const count = props.isMaxTag ? label.slice(0, -3).slice(1) : label; return ( {showTags ? label : intl.formatMessage( { id: 'common.select.count' }, { count: count } )} ); }; const handleOnSearch = (value: string) => { if (restProps.showSearch?.onSearch) { restProps.showSearch?.onSearch?.(value); } else { const filteredOptions = options?.filter((option: any) => option.label.toLowerCase().includes(value.toLowerCase()) ) as Global.BaseOption[]; setOptionsList(filteredOptions || []); checkAllSelection(filteredOptions || []); } }; const handleOnBlur = (e: any) => { restProps.onBlur?.(e); }; const handleOnFocus = (e: any) => { restProps.onFocus?.(e); }; const handleOnOpenChange = (open: boolean) => { if (!open) { checkAllSelection(options as Global.BaseOption[]); setOptionsList(options || []); } }; useEffect(() => { const input = selectRef.current?.querySelector?.('input'); if (!input) return; const handler = (event: KeyboardEvent) => { if ( event.key === 'Backspace' && (input as HTMLInputElement).value === '' ) { event.stopPropagation(); event.preventDefault(); } }; input.addEventListener('keydown', handler); return () => { input.removeEventListener('keydown', handler); }; }, [selectRef.current]); useImperativeHandle(ref, () => ({ focus: () => { selectorRef.current?.focus(); }, blur: () => { selectorRef.current?.blur(); } })); return (
{props.children}
); }); export default SimpleSelect;