fix(components): [select/select-v2] show empty slot when remote search empty#23195
Conversation
|
👋 @YXY-cell, seems like this is your first time contribution to element-plus. |
commit: |
|
🧪 Playground Preview: https://element-plus.run/?pr=23195 |
📝 WalkthroughWalkthroughTreats a provided Changes
Sequence Diagram(s)(Skipped — change is a focused visibility condition tweak and small test additions; no complex multi-component sequential flow requiring visualization.) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/components/select/__tests__/select.test.ts (1)
4243-4292: Suggest additional test coverage for edge cases.The test successfully verifies that the empty slot is shown when a remote search returns no results. Consider adding the following test cases to ensure comprehensive coverage:
Negative test: Verify that without an empty slot, the dropdown hides when remote search returns empty results (to confirm the fix only applies when the slot is present).
Debouncing interaction: Test the initial focus behavior when
debouncingis active andpreviousQueryis empty, to validate the edge case identified in the implementation review.Loading state: Verify that the empty slot is shown correctly when
loadingtransitions fromtruetofalsewith no results.Non-remote mode: Ensure that the empty slot behavior is unaffected in non-remote mode (existing functionality preserved).
🔎 Example test for negative case (no empty slot)
test('should hide dropdown when remote search returns empty without empty slot', async () => { const wrapper = mount({ components: { 'el-select': Select, 'el-option': Option, }, template: ` <el-select v-model="value" filterable remote :remote-method="remoteMethod" > <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" /> </el-select> `, setup() { const value = ref('') const options = ref<any[]>([]) const remoteMethod = (query) => { options.value = [] // Always return empty } return { value, options, remoteMethod } }, }) const select = wrapper.findComponent(Select) const input = wrapper.find('input') await input.trigger('click') await input.setValue('query') await nextTick() await nextTick() // Without empty slot, dropdown should hide when no options expect((select.vm as any).dropdownMenuVisible).toBe(false) })
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/components/select/__tests__/select.test.tspackages/components/select/src/useSelect.ts
🧰 Additional context used
🧬 Code graph analysis (1)
packages/components/select/__tests__/select.test.ts (1)
packages/components/table/__tests__/table-test-common.ts (1)
mount(21-24)
🔇 Additional comments (3)
packages/components/select/src/useSelect.ts (3)
7-7: LGTM: Standard Vue Composition API import.The addition of
useSlotsis appropriate for accessing template slots at runtime.
63-63: LGTM: Proper slots initialization.The slots are correctly initialized using
useSlots()and positioned appropriately within the composable setup.
249-262: The logic correctly adds support for showing the dropdown whenremotemode is active and anemptyslot is provided. The condition(!debouncing.value || !isEmpty(states.previousQuery))handles this appropriately.On initial focus of a remote select with an empty slot,
debouncing.valueisfalseandpreviousQueryisnull. The condition evaluates to(!false || !isEmpty(null))=(true || false)=true, so the dropdown will display immediately, allowing the empty slot to be visible.The debouncing check prevents the dropdown from showing only when both
debouncing=trueANDpreviousQueryis empty—which correctly prevents displaying stale results during an active debounce period before the first query is sent.Likely an incorrect or invalid review comment.
|
如何申请合并这个代码 |
|
Once approved by other reviewers, the data can be merged. |
happy new year!Thank for your guide |
happy new year ❤️ |
I’m sorry to bother you, and I hope I’m not interrupting your vacation. Since I’m a beginner, I’d like to ask you a question: generally speaking, how many reviewers need to approve for the code to be merged? |
Dsaquel
left a comment
There was a problem hiding this comment.
It looks like select-v2 has the same problem, can you fix it too ?
I ‘ll try it later,thank for your appreciation! |
Should I create a new issue and submit a new PR, or make the changes directly on this existing PR? |
You can make changes in this PR, we often update select and select-v2 together for related fixes. |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/components/select-v2/src/useSelect.ts (1)
393-406: LGTM: Logic correctly implements empty slot visibility in remote mode.The added condition
(props.remote && !!slots.empty)appropriately keeps the dropdown open when a custom empty slot is provided during remote searches with no results. This prevents the dropdown from closing and hiding the empty-state content.Optional: Add clarifying comment
Consider adding a brief inline comment to explain the remote + empty slot condition for future maintainability:
const dropdownMenuVisible = computed({ get() { return ( expanded.value && (props.loading || !isRemoteSearchEmpty.value || + // Keep dropdown open in remote mode to show custom empty slot content (props.remote && !!slots.empty)) && (!debouncing.value || !isEmpty(states.previousQuery)) ) },
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/components/select-v2/__tests__/select.test.tspackages/components/select-v2/src/useSelect.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-26T15:08:21.704Z
Learnt from: btea
Repo: element-plus/element-plus PR: 23222
File: packages/components/timeline/__tests__/timeline.test.tsx:172-181
Timestamp: 2025-12-26T15:08:21.704Z
Learning: In Timeline component tests (`packages/components/timeline/__tests__/timeline.test.tsx`), when testing non-TimelineItem content in the default slot using functional component syntax with `mount(() => <TimeLine>...</TimeLine>)`, the test framework strips wrapper elements and `wrapper.element.innerHTML` contains only the text content, not the wrapper div HTML.
Applied to files:
packages/components/select-v2/__tests__/select.test.ts
🔇 Additional comments (3)
packages/components/select-v2/src/useSelect.ts (2)
7-7: LGTM: Correct import for slots access.The
useSlotsimport is properly added to access template slots in the composition API.
56-56: LGTM: Proper slots initialization.The slots reference is correctly initialized using
useSlots()and will be reactive to slot changes.packages/components/select-v2/__tests__/select.test.ts (1)
2732-2792: LGTM: Comprehensive test for empty slot in remote search scenarios.The test properly validates the new behavior:
- Verifies dropdown stays open when empty slot is present in remote mode
- Tests the transition between empty → populated → empty states
- Correctly uses fake timers to handle debounced remote method
- Properly cleans up with
vi.useRealTimers()
Hello,I recovered select-v2,can you check it please?thanks |
|
Hello, @YXY-cell, your PR title does not meet the standards, please refer to here. |
Dsaquel
left a comment
There was a problem hiding this comment.
Thank you and happy new year 😃 .
|
@YXY-cell Thanks for your contribution! ❤️ |
Thanks!Happy new year❤️ |

Fixes #23191
What is this change?
Fixes the issue where the dropdown menu prevents the empty slot from showing when remote search returns empty.
Why is this change needed?
When
remoteis enabled and search results are empty, the dropdown menu logic was incorrectly hiding the menu, making the#emptyslot (e.g., "Add Option" button) invisible to users. This fix adds a condition to check for the empty slot.Summary by CodeRabbit
Tests
Bug Fixes
✏️ Tip: You can customize this high-level summary in your review settings.