Skip to content

fix(components): [select/select-v2] show empty slot when remote search empty#23195

Merged
Dsaquel merged 5 commits into
element-plus:devfrom
YXY-cell:fix/23191-select-remote-empty
Jan 2, 2026
Merged

fix(components): [select/select-v2] show empty slot when remote search empty#23195
Dsaquel merged 5 commits into
element-plus:devfrom
YXY-cell:fix/23191-select-remote-empty

Conversation

@YXY-cell
Copy link
Copy Markdown
Contributor

@YXY-cell YXY-cell commented Dec 23, 2025

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 remote is enabled and search results are empty, the dropdown menu logic was incorrectly hiding the menu, making the #empty slot (e.g., "Add Option" button) invisible to users. This fix adds a condition to check for the empty slot.

Summary by CodeRabbit

  • Tests

    • Added tests verifying select components (v1 and v2) display a custom empty-state template when remote searches return no results.
  • Bug Fixes

    • Fixed dropdown visibility so custom empty-state templates are shown correctly during remote search flows when no options are found.

✏️ Tip: You can customize this high-level summary in your review settings.

@pull-request-triage
Copy link
Copy Markdown

👋 @YXY-cell, seems like this is your first time contribution to element-plus.
Please make sure that you have read our guidelines and code of conduct before making a contribution.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Dec 23, 2025

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Dec 24, 2025

Open in StackBlitz

pnpm add https://pkg.pr.new/element-plus/element-plus@23195
npm i https://pkg.pr.new/element-plus/element-plus@23195
yarn add https://pkg.pr.new/element-plus/[email protected]

commit: d374e93

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Dec 24, 2025

🧪 Playground Preview: https://element-plus.run/?pr=23195
Please comment the example via this playground if needed.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 26, 2025

📝 Walkthrough

Walkthrough

Treats a provided empty slot as a valid reason to keep the select dropdown open during remote searches that return no options; adds tests validating the empty-slot rendering and popper visibility for remote-empty responses (tests duplicated in the diff).

Changes

Cohort / File(s) Summary
Select core logic
packages/components/select/src/useSelect.ts, packages/components/select-v2/src/useSelect.ts
Import useSlots() and add a slots.empty check to the dropdownMenuVisible condition so the dropdown remains open when remote mode is active and an #empty slot is provided.
Tests (select)
packages/components/select/__tests__/select.test.ts
Add test "should show empty slot correctly in remote search scenarios" that mounts a remote select, triggers a query with no results, and asserts the custom #empty slot and popper are visible. Test appears twice in diff (duplication).
Tests (select-v2)
packages/components/select-v2/__tests__/select.test.ts
Add similar remote-search tests for Select v2 that verify #empty slot rendering across empty/non-empty remote responses; uses fake timers to simulate remoteMethod behavior.

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

  • Dsaquel
  • rzzf

Poem

🐰 I peeked where options used to be,
An empty slot waved back at me.
Though no choices hopped into view,
The popper stayed — the meadow true.
Hooray, the empty slot gets through! 🥕✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description check ✅ Passed The description adequately explains the fix, references the linked issue #23191, and clearly states the problem and solution, though minimal structure.
Linked Issues check ✅ Passed The changes successfully address issue #23191 by adding empty slot visibility logic to both select and select-v2 components when remote search yields no results.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the empty slot visibility issue in select and select-v2 components with corresponding tests, with no unrelated modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title clearly and accurately summarizes the main change: enabling the empty slot to display when remote search returns no results in both select and select-v2 components.
✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  1. 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).

  2. Debouncing interaction: Test the initial focus behavior when debouncing is active and previousQuery is empty, to validate the edge case identified in the implementation review.

  3. Loading state: Verify that the empty slot is shown correctly when loading transitions from true to false with no results.

  4. 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

📥 Commits

Reviewing files that changed from the base of the PR and between 1a1c23e and bb8cac3.

📒 Files selected for processing (2)
  • packages/components/select/__tests__/select.test.ts
  • packages/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 useSlots is 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 when remote mode is active and an empty slot is provided. The condition (!debouncing.value || !isEmpty(states.previousQuery)) handles this appropriately.

On initial focus of a remote select with an empty slot, debouncing.value is false and previousQuery is null. 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=true AND previousQuery is 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.

@btea btea changed the title fix(components): [Select] show empty slot when remote search empty fix(components): [select] show empty slot when remote search empty Dec 28, 2025
@YXY-cell
Copy link
Copy Markdown
Contributor Author

如何申请合并这个代码

@btea
Copy link
Copy Markdown
Member

btea commented Dec 31, 2025

Once approved by other reviewers, the data can be merged.

Comment thread packages/components/select/__tests__/select.test.ts Outdated
Comment thread packages/components/select/__tests__/select.test.ts Outdated
Copy link
Copy Markdown
Member

@rzzf rzzf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me, thank you!

@YXY-cell
Copy link
Copy Markdown
Contributor Author

looks good to me, thank you!

happy new year!Thank for your guide

@rzzf
Copy link
Copy Markdown
Member

rzzf commented Jan 1, 2026

happy new year!Thank for your guide

happy new year ❤️

@YXY-cell
Copy link
Copy Markdown
Contributor Author

YXY-cell commented Jan 2, 2026

Once approved by other reviewers, the data can be merged.

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?

@rzzf rzzf requested a review from Dsaquel January 2, 2026 11:51
Copy link
Copy Markdown
Member

@Dsaquel Dsaquel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like select-v2 has the same problem, can you fix it too ?

@YXY-cell
Copy link
Copy Markdown
Contributor Author

YXY-cell commented Jan 2, 2026

It looks like select-v2 has the same problem, can you fix it too ?

I ‘ll try it later,thank for your appreciation!

@YXY-cell
Copy link
Copy Markdown
Contributor Author

YXY-cell commented Jan 2, 2026

It looks like select-v2 has the same problem, can you fix it too ?

Should I create a new issue and submit a new PR, or make the changes directly on this existing PR?

@Dsaquel
Copy link
Copy Markdown
Member

Dsaquel commented Jan 2, 2026

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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 17e7608 and d374e93.

📒 Files selected for processing (2)
  • packages/components/select-v2/__tests__/select.test.ts
  • packages/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 useSlots import 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()

@YXY-cell
Copy link
Copy Markdown
Contributor Author

YXY-cell commented Jan 2, 2026

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.

Hello,I recovered select-v2,can you check it please?thanks

@Dsaquel Dsaquel changed the title fix(components): [select] show empty slot when remote search empty fix(components): [select/select-v2] show empty slot when remote search empty Jan 2, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jan 2, 2026

Hello, @YXY-cell, your PR title does not meet the standards, please refer to here.
你好,@YXY-cell,你的 PR 标题不符合规范,请参考这里

@github-actions github-actions Bot added the CommitMessage::Unqualified Unqualified commit message label Jan 2, 2026
Copy link
Copy Markdown
Member

@Dsaquel Dsaquel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you and happy new year 😃 .

@Dsaquel Dsaquel merged commit 4b04769 into element-plus:dev Jan 2, 2026
18 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jan 2, 2026

@YXY-cell Thanks for your contribution! ❤️

@YXY-cell
Copy link
Copy Markdown
Contributor Author

YXY-cell commented Jan 3, 2026

Thank you and happy new year 😃 .谢谢你,新年快乐 😃。

Thanks!Happy new year❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Component] [select] 当el-select的所有options都被清空时,无法下拉,也就无法展示empty插槽及header等

4 participants