diff --git a/src/BaseSelect/index.tsx b/src/BaseSelect/index.tsx index 0389f623..00c7f6b8 100644 --- a/src/BaseSelect/index.tsx +++ b/src/BaseSelect/index.tsx @@ -1,6 +1,6 @@ import type { AlignType, BuildInPlacements } from '@rc-component/trigger'; import { clsx } from 'clsx'; -import { getDOM, isNonNullable, useEvent } from '@rc-component/util'; +import { getDOM, isNonNullable, isReactRenderable, useEvent } from '@rc-component/util'; import type { ScrollConfig, ScrollTo } from '@rc-component/virtual-list'; import * as React from 'react'; import { useAllowClear } from '../hooks/useAllowClear'; @@ -360,7 +360,7 @@ const BaseSelect = React.forwardRef((props, ref) // ============================== Open ============================== // Not trigger `open` when `notFoundContent` is empty - const emptyListContent = !notFoundContent && emptyOptions; + const emptyListContent = !isReactRenderable(notFoundContent) && emptyOptions; const [rawOpen, mergedOpen, triggerOpen, lockOptions] = useOpen( defaultOpen || false, diff --git a/src/OptionList.tsx b/src/OptionList.tsx index 87b9094a..39cf5fd2 100644 --- a/src/OptionList.tsx +++ b/src/OptionList.tsx @@ -1,5 +1,5 @@ import { clsx } from 'clsx'; -import { KeyCode, omit, pickAttrs, useMemo } from '@rc-component/util'; +import { isReactRenderable, KeyCode, omit, pickAttrs, useMemo } from '@rc-component/util'; import List, { type ListRef, type ScrollConfig } from '@rc-component/virtual-list'; import * as React from 'react'; import { useEffect } from 'react'; @@ -446,10 +446,12 @@ const OptionList: React.ForwardRefRenderFunction = (_, r const mergedLabel = getLabel(item); const iconVisible = - !menuItemSelectedIcon || typeof menuItemSelectedIcon === 'function' || selected; + !isReactRenderable(menuItemSelectedIcon) || + typeof menuItemSelectedIcon === 'function' || + selected; // https://github.com/ant-design/ant-design/issues/34145 - const content = typeof mergedLabel === 'number' ? mergedLabel : mergedLabel || value; + const content = isReactRenderable(mergedLabel) ? mergedLabel : value; // https://github.com/ant-design/ant-design/issues/26717 let optionTitle = isTitleType(content) ? content.toString() : undefined; if (title !== undefined) { diff --git a/src/Select.tsx b/src/Select.tsx index 9735154f..167578e7 100644 --- a/src/Select.tsx +++ b/src/Select.tsx @@ -369,10 +369,7 @@ const Select = React.forwardRef( // ========================== Render ========================== const showHasValueCls = - displayValue && - displayValue.label !== null && - displayValue.label !== undefined && - String(displayValue.label).trim() !== ''; + displayValue && isNonNullable(displayValue.label) && String(displayValue.label).trim() !== ''; // Render value // Only render value when not using custom input in combobox mode diff --git a/tests/renderability.test.tsx b/tests/renderability.test.tsx new file mode 100644 index 00000000..b01e7db4 --- /dev/null +++ b/tests/renderability.test.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import Select from '../src'; + +it('opens an empty dropdown containing zero', () => { + const { baseElement } = render(, + ); + expect(baseElement.querySelectorAll('.rc-select-item-option-state')).toHaveLength(1); + expect( + baseElement.querySelector('.rc-select-item-option-selected .rc-select-item-option-state') + .textContent, + ).toBe('0'); +}); + +it('keeps a zero option label in the dropdown and selected value', () => { + const { container, baseElement } = render( +