-
Notifications
You must be signed in to change notification settings - Fork 2.5k
feat: add ant-design-vue 4.x component recognition patch #619
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
PiedPiper911
wants to merge
2
commits into
alibaba:main
Choose a base branch
from
PiedPiper911:fix/ant-design-vue-components-601
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| import type { PageController } from '../PageController' | ||
|
|
||
| const clearFunctions: (() => void)[] = [] | ||
|
|
||
| /** | ||
| * Patch ant-design-vue 4.x Select and TreeSelect components. | ||
| * | ||
| * ant-design-vue's Select/TreeSelect use a div wrapping an invisible | ||
| * input[role="combobox"]. The input holds ARIA attributes and the current | ||
| * value, but since it's invisible (offsetWidth === 0), it never appears in | ||
| * the cleaned DOM tree. This patch copies ARIA attributes from the hidden | ||
| * input to the visible parent .ant-select-selector so the LLM can see and | ||
| * interact with the component. | ||
| */ | ||
| function fixAntdvSelect() { | ||
| const inputs = [...document.querySelectorAll('input[role="combobox"]')] | ||
| for (const input of inputs) { | ||
| const parent = input.closest('.ant-select-selector') | ||
| if (!parent || !(parent instanceof HTMLElement)) continue | ||
|
|
||
| // Always refresh ARIA attributes from the hidden input to the parent div. | ||
| // This ensures the LLM sees up-to-date state (e.g., aria-expanded changes). | ||
| for (const attr of ['aria-label', 'aria-expanded', 'aria-controls', 'aria-haspopup', 'aria-autocomplete']) { | ||
| if (input.hasAttribute(attr)) { | ||
| parent.setAttribute(attr, input.getAttribute(attr)!) | ||
| } | ||
| } | ||
|
|
||
| // Copy the current value as a data attribute so flatTreeToString can read it. | ||
| const inputEl = input as HTMLInputElement | ||
| if (inputEl.value) { | ||
| parent.setAttribute('data-value', inputEl.value) | ||
| } else { | ||
| parent.removeAttribute('data-value') | ||
| } | ||
|
|
||
| // Mark as patched to avoid duplicate processing. | ||
| parent.setAttribute('data-antdv-patched', 'true') | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Patch ant-design-vue 4.x TreeSelect dropdown items. | ||
| * | ||
| * TreeSelect dropdowns are teleported to <body> and use .ant-select-tree-* | ||
| * classes. The tree nodes need cursor: pointer to be recognized as interactive | ||
| * by isInteractiveElement(). | ||
| */ | ||
| function fixAntdvTreeSelectDropdown() { | ||
| const treeNodes = [...document.querySelectorAll('.ant-select-tree-treenode')] | ||
| for (const node of treeNodes) { | ||
| if (!(node instanceof HTMLElement)) continue | ||
|
|
||
| // The content node needs cursor: pointer for isInteractiveElement(). | ||
| const content = node.querySelector('.ant-select-tree-node-content-wrapper') | ||
| if (content instanceof HTMLElement && !content.hasAttribute('data-antdv-patched')) { | ||
| content.style.setProperty('cursor', 'pointer', 'important') | ||
| content.setAttribute('data-antdv-patched', 'true') | ||
| } | ||
|
|
||
| // The switcher (expand/collapse icon) should also be interactive. | ||
| const switcher = node.querySelector('.ant-select-tree-switcher') | ||
| if (switcher instanceof HTMLElement && !switcher.hasAttribute('data-antdv-patched')) { | ||
| switcher.style.setProperty('cursor', 'pointer', 'important') | ||
| switcher.setAttribute('role', 'button') | ||
| switcher.setAttribute('data-antdv-patched', 'true') | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Patch ant-design-vue 4.x disabled components so they remain visible. | ||
| * | ||
| * By default, disabled elements (with the `disabled` attribute or | ||
| * .ant-input-disabled class) are excluded from the interactive element tree | ||
| * by isInteractiveElement(). This patch ensures disabled components are at | ||
| * least visible to the LLM by adding role="button" and aria-disabled="true" | ||
| * to their wrapper elements. The LLM can then see the component exists and | ||
| * report its disabled state to the user. | ||
| */ | ||
| function fixAntdvDisabledComponents() { | ||
| // Disabled inputs: .ant-input-disabled or input[disabled] with .ant-input wrapper | ||
| const disabledInputs = [...document.querySelectorAll('.ant-input-disabled, .ant-input-affix-wrapper-disabled')] | ||
| for (const wrapper of disabledInputs) { | ||
| if (!(wrapper instanceof HTMLElement)) continue | ||
| if (!wrapper.hasAttribute('data-antdv-disabled-patched')) { | ||
| wrapper.setAttribute('aria-disabled', 'true') | ||
| wrapper.setAttribute('data-antdv-disabled-patched', 'true') | ||
| // Ensure the wrapper is visible (has dimensions) even though the | ||
| // inner input is disabled. The wrapper itself should still be | ||
| // recognized as an element in the DOM tree. | ||
| wrapper.style.setProperty('cursor', 'not-allowed', 'important') | ||
| } | ||
| } | ||
|
|
||
| // Disabled selects: .ant-select-disabled | ||
| const disabledSelects = [...document.querySelectorAll('.ant-select-disabled')] | ||
| for (const select of disabledSelects) { | ||
| if (!(select instanceof HTMLElement)) continue | ||
| if (!select.hasAttribute('data-antdv-disabled-patched')) { | ||
| select.setAttribute('aria-disabled', 'true') | ||
| select.setAttribute('data-antdv-disabled-patched', 'true') | ||
| } | ||
| } | ||
|
|
||
| // Disabled buttons: .ant-btn-disabled or button[disabled] | ||
| const disabledButtons = [...document.querySelectorAll('.ant-btn-disabled')] | ||
| for (const btn of disabledButtons) { | ||
| if (!(btn instanceof HTMLElement)) continue | ||
| if (!btn.hasAttribute('data-antdv-disabled-patched')) { | ||
| btn.setAttribute('aria-disabled', 'true') | ||
| btn.setAttribute('data-antdv-disabled-patched', 'true') | ||
| } | ||
| } | ||
| } | ||
|
|
||
| export function patchAntDesignVue(pageController: PageController) { | ||
| pageController.addEventListener('beforeUpdate', () => { | ||
| fixAntdvSelect() | ||
| fixAntdvTreeSelectDropdown() | ||
| fixAntdvDisabledComponents() | ||
| }) | ||
| pageController.addEventListener('afterUpdate', () => { | ||
| for (const fn of clearFunctions) fn() | ||
| clearFunctions.length = 0 | ||
| }) | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the disabled AntDV control is a non-interactive wrapper or a disabled input/select, this only adds
aria-disabled, but the extractor does not usearia-disabledas an interactive signal or include it in the default emitted attributes. As a result, disabled AntDV inputs/selects still get no highlight index and usually remain invisible inflatTreeToString, so the new disabled-state patch does not achieve its stated behavior unless another interactive signal such asrole/tabindexor an explicit whitelist/default attribute is added.Useful? React with 👍 / 👎.