Skip to content

feat: support disabled prop#638

Merged
zombieJ merged 1 commit into
masterfrom
codex/trigger-disabled
Jul 10, 2026
Merged

feat: support disabled prop#638
zombieJ merged 1 commit into
masterfrom
codex/trigger-disabled

Conversation

@zombieJ

@zombieJ zombieJ commented Jul 10, 2026

Copy link
Copy Markdown
Member

Summary

  • add a disabled prop that masks effective popup visibility while preserving the existing controlled or uncontrolled open state
  • add a hover Tooltip demo whose Button toggles disabled on click
  • document the new prop in English and Chinese

Behavior

When a hover-triggered popup is already open, setting disabled hides it immediately. Setting disabled back to false restores it while the existing open state remains active, without requiring another mouse enter.

disabled only affects mergedOpen; it does not add separate event guards, effects, open-state storage, or UniqueProvider state.

Related: ant-design/ant-design#57290

Validation

  • ut coverage --runInBand (17 suites, 132 passed, 1 skipped)
  • ut tsc
  • ut docs:build
  • ut x prettier@3.9.4 --check docs/examples/disabled.tsx docs/demos/disabled.md

Summary by CodeRabbit

  • 新功能

    • 新增 disabled 配置,可暂时隐藏弹层,同时保留当前打开状态。
    • 提供禁用与恢复 Tooltip 显示的示例。
  • 文档

    • 更新中英文 API 文档,补充 disabled 配置说明及默认值。
    • 新增禁用 Tooltip 的演示页面。
  • 测试

    • 增加悬浮触发和受控模式下的禁用行为测试。

@vercel

vercel Bot commented Jul 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
trigger Ready Ready Preview, Comment Jul 10, 2026 8:42am

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a0d971e5-7071-4fd3-af74-e10417eba49c

📥 Commits

Reviewing files that changed from the base of the PR and between 8e1a491 and 49bcd0c.

📒 Files selected for processing (6)
  • README.md
  • README.zh-CN.md
  • docs/demos/disabled.md
  • docs/examples/disabled.tsx
  • src/index.tsx
  • tests/basic.test.jsx

Walkthrough

新增 TriggerProps.disabled 配置。mergedOpen 在禁用时抑制 Popup 显示但保留内部 open 状态,并补充中文文档、示例及 hover 和受控模式测试。

Changes

Trigger 禁用可见性

Layer / File(s) Summary
disabled 属性与可见性计算
src/index.tsx, README.md, README.zh-CN.md
新增可选 disabled 属性,默认值为 falsemergedOpen 同步影响 UniqueProvider 与 Popup 的显示状态。
禁用 Tooltip 示例
docs/demos/disabled.md, docs/examples/disabled.tsx
新增示例页面及组件,通过按钮切换 hover Tooltip 的禁用状态。
禁用行为测试
tests/basic.test.jsx
覆盖 hover 和受控 popupVisible 场景中的隐藏、恢复及 onOpenChange 行为。

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  actor User
  participant DisabledDemo
  participant Trigger
  participant UniqueProvider
  participant Popup

  User->>DisabledDemo: 点击切换 disabled
  DisabledDemo->>Trigger: 更新 disabled 属性
  User->>Trigger: 悬浮触发 Tooltip
  Trigger->>UniqueProvider: 同步 mergedOpen
  Trigger->>Popup: 传递 mergedOpen
  Popup-->>User: 显示或隐藏弹层
Loading

Possibly related PRs

Poem

小兔挥爪关 Tooltip,
弹层悄悄不现形。
open 状态仍安稳,
再挥一爪恢复明。
测试青草香,文档月光清。

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/trigger-disabled

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown

React Doctor found 8 issues in 1 file · 8 warnings · score 71 / 100 (Needs work) · vs master

8 warnings

src/index.tsx

  • ⚠️ L155 Large component is hard to read and change no-giant-component
  • ⚠️ L198 Empty default prop breaks memo rerender-memo-with-default-value
  • ⚠️ L383 Missing effect dependencies exhaustive-deps
  • ⚠️ L436 Derived state stored in an effect no-derived-state-effect
  • ⚠️ L515 Missing effect dependencies exhaustive-deps
  • ⚠️ L515 Missing effect dependencies exhaustive-deps
  • ⚠️ L579 Missing effect dependencies exhaustive-deps
  • ⚠️ L770 Static value rebuilt every render prefer-module-scope-static-value

Reviewed by React Doctor for commit 49bcd0c. See inline comments for fixes.

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown

❌ Deploy failed

PR preview ❌ Failed ❌ Failed
🔗 Preview https://react-component-trigger-preview-pr-638.surge.sh (may be unavailable)
📝 Commit49bcd0c
🪵 LogsView logs
📋 Build log (last lines)
npm error
npm error Could not resolve dependency:
npm error peer eslint@"^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" from eslint-plugin-react@7.37.5
npm error node_modules/eslint-plugin-react
npm error   dev eslint-plugin-react@"^7.37.5" from the root project
npm error   eslint-plugin-react@"^7.32.2" from @umijs/fabric@4.0.1
npm error   node_modules/@umijs/fabric
npm error     @umijs/fabric@"^4.0.0" from rc-test@7.1.3
npm error     node_modules/rc-test
npm error       dev rc-test@"^7.1.3" from the root project
npm error
npm error Conflicting peer dependency: eslint@9.39.4
npm error node_modules/eslint
npm error   peer eslint@"^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" from eslint-plugin-react@7.37.5
npm error   node_modules/eslint-plugin-react
npm error     dev eslint-plugin-react@"^7.37.5" from the root project
npm error     eslint-plugin-react@"^7.32.2" from @umijs/fabric@4.0.1
npm error     node_modules/@umijs/fabric
npm error       @umijs/fabric@"^4.0.0" from rc-test@7.1.3
npm error       node_modules/rc-test
npm error         dev rc-test@"^7.1.3" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
npm error For a full report see:
npm error /home/runner/.npm/_logs/2026-07-10T08_43_07_144Z-eresolve-report.txt
npm error A complete log of this run can be found in: /home/runner/.npm/_logs/2026-07-10T08_43_07_144Z-debug-0.log

🤖 Powered by surge-preview

@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.28%. Comparing base (8e1a491) to head (49bcd0c).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #638   +/-   ##
=======================================
  Coverage   97.28%   97.28%           
=======================================
  Files          17       17           
  Lines         956      957    +1     
  Branches      268      275    +7     
=======================================
+ Hits          930      931    +1     
  Misses         26       26           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a disabled prop to the Trigger component, allowing users to temporarily suppress popup visibility without resetting its current open state. To support this, UniqueProvider is updated with a setDisabled method and references to track active and disabled open states. Comprehensive tests are also added to verify this behavior. A review comment identifies a potential bug where outside click detection fails to clear the logical open state when autoDestroy is enabled and the trigger is disabled, as the unmounted popup removes the window click listeners; a fix is suggested to register listeners using rawOpen and targetEle instead.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/index.tsx Outdated
// Click to hide is special action since click popup element should not hide
const onPopupPointerDown = useWinClick(
mergedOpen,
rawOpen,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Potential Bug: Outside click detection fails when autoDestroy is enabled and trigger is disabled\n\nWhen disabled is true, mergedOpen becomes false, which causes the popup to hide. If autoDestroy is true, the popup element is completely unmounted once the hide transition completes, setting popupEle to null.\n\nIn useWinClick.ts, the window click listener is only registered if popupEle is truthy:\ntypescript\nReact.useEffect(() => {\n if (clickToHide && popupEle && (!mask || maskClosable)) {\n // ...\n\nBecause popupEle becomes null, the window click listeners are removed. Consequently, clicking outside the trigger while it is disabled will not clear the logical open state (rawOpen remains true). When disabled is later toggled back to false, the popup will unexpectedly reappear.\n\n#### Suggested Fix\nUpdate useWinClick.ts to register the event listeners when open (which is rawOpen) is true, even if popupEle is null (using targetEle to resolve the window/document):\n\ntypescript\n// src/hooks/useWinClick.ts\nexport default function useWinClick(\n open: boolean,\n clickToHide: boolean,\n targetEle: HTMLElement,\n popupEle: HTMLElement,\n mask: boolean,\n maskClosable: boolean,\n inPopupOrChild: (target: EventTarget) => boolean,\n triggerOpen: (open: boolean) => void,\n) {\n const openRef = React.useRef<boolean>(open);\n openRef.current = open;\n\n const popupPointerDownRef = React.useRef<boolean>(false);\n\n React.useEffect(() => {\n if (clickToHide && (popupEle || open) && (!mask || maskClosable)) {\n const onPointerDown = () => {\n popupPointerDownRef.current = false;\n };\n\n const onTriggerClose = (e: MouseEvent) => {\n if (\n openRef.current &&\n !inPopupOrChild(e.composedPath?.()?.[0] || e.target) &&\n !popupPointerDownRef.current\n ) {\n triggerOpen(false);\n }\n };\n\n const win = getWin(popupEle || targetEle);\n\n win.addEventListener('pointerdown', onPointerDown, true);\n win.addEventListener('mousedown', onTriggerClose, true);\n win.addEventListener('contextmenu', onTriggerClose, true);\n // ...\n

Comment thread src/index.tsx Outdated
}
}
}, [mergedOpen, targetEle]);
}, [mergedOpen, targetEle, disabled]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

React Doctor · react-doctor/exhaustive-deps (warning)

useLayoutEffect can run with a stale uniqueContext, unique, openUncontrolled, parentContext, uniqueContext.show, mouseEnterDelay, uniqueContext.hide, mouseLeaveDelay & show your users old data.

Fix → Don't blindly add missing dependencies. Read the hook callback first.

Bad:
useEffect(() => {
setCount(count + 1);
}, [count]);

Better:
useEffect(() => {
setCount((currentCount) => currentCount + 1);
}, []);

If the missing value is recreated every render, move it inside the hook or stabilize it before adding it to deps.

Docs

@zombieJ zombieJ force-pushed the codex/trigger-disabled branch from 780b8aa to 49bcd0c Compare July 10, 2026 08:41
@zombieJ zombieJ marked this pull request as ready for review July 10, 2026 08:50
@zombieJ zombieJ merged commit f6e0c74 into master Jul 10, 2026
12 checks passed
@zombieJ zombieJ deleted the codex/trigger-disabled branch July 10, 2026 08:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant