Skip to content

fix(core/dropdown-button): accessibility consistency in dropdown-button-icon - #2654

Open
GayatriK2002 wants to merge 4 commits into
siemens:mainfrom
GayatriK2002:fix-4336/dropdown-accessibility
Open

fix(core/dropdown-button): accessibility consistency in dropdown-button-icon#2654
GayatriK2002 wants to merge 4 commits into
siemens:mainfrom
GayatriK2002:fix-4336/dropdown-accessibility

Conversation

@GayatriK2002

@GayatriK2002 GayatriK2002 commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

💡 What is the current behavior?

  • EMPTY_PROP = Symbol() causes ARIA attributes to render as "Symbol()" literal in Vue framework; Vue wrapper bypasses ARIA props, screen reader reads "symbol" instead of actual labels
  • dropdown-button-icon preview examples in vue didn't have space/enter interactivity
  • dropdown-button-icon preview examples were taking extra width while focusing on them with tab button

GitHub Issue Number: #
Jira Issue Number: 4336

🆕 What is the new behavior?

  • Updated Vue wrapper with patch (EMPTY_PROP = {}); updated condition in utils.ts ensures ARIA properties always pass through via (key.startsWith(ARIA_PROP_PREFIX) && value !== EMPTY_PROP), fixing "Symbol()" rendering.
  • dropdown-button-icon preview examples in vue now have space/enter interactivity
  • dropdown-button-icon preview examples now gets highlighted properly with css changes in preview example
  • ES2017 target required Babel's _typeof helper when transpiling Symbol(), which was unnecessary overhead so updated them to ES2020, but the TypeScript target updates are a "nice-to-have" optimization, not a requirement for the fix to work

🏁 Checklist

A pull request can only be merged if all of these conditions are met (where applicable):

  • 🦮 Accessibility (a11y) features were implemented
  • 🗺️ Internationalization (i18n) - no hard coded strings
  • 📲 Responsiveness - components handle viewport changes and content overflow gracefully
  • 📕 Add or update a Storybook story
  • 📄 Documentation was reviewed/updated siemens/ix-docs
  • 🧪 Unit tests were added/updated and pass (pnpm test)
  • 📸 Visual regression tests were added/updated and pass (Guide)
  • 🧐 Static code analysis passes (pnpm lint)
  • 🏗️ Successful compilation (pnpm build, changes pushed)

👨‍💻 Help & support

Summary by CodeRabbit

  • Bug Fixes

    • Improved dropdown button layout so content aligns consistently at the start across Angular, HTML, React, and Vue examples.
    • Corrected Vue dropdown examples to ensure dropdown items render and behave as expected.
    • Improved handling of optional accessibility attributes in Vue components.
  • Compatibility

    • Updated supported TypeScript compilation targets to ES2020 across relevant packages and testing tools.

@netlify

netlify Bot commented Jul 15, 2026

Copy link
Copy Markdown

Deploy Preview for ix-storybook canceled.

Name Link
🔨 Latest commit 1e06d47
🔍 Latest deploy log https://app.netlify.com/projects/ix-storybook/deploys/6a58a9a8e4091c000887d7fe

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Dropdown preview updates

Layer / File(s) Summary
Preview alignment and component imports
packages/*/src/preview-examples/dropdown-button*, packages/vue-test-app/src/preview-examples/*.vue
Dropdown button previews set align-items: flex-start; Vue examples import IxDropdownItem.

Vue prop handling

Layer / File(s) Summary
Vue runtime sentinel and patch wiring
patches/@stencil__vue-output-target.patch, pnpm-workspace.yaml
The Vue output-target runtime uses an empty object sentinel, and the workspace registers its patch.
Vue wrapper prop filtering
packages/vue/src/vue-component-lib/utils.ts
Vue prop construction uses the shared sentinel and excludes sentinel-valued aria* properties.

TypeScript target updates

Layer / File(s) Summary
ES2020 compiler configurations
packages/angular/tsconfig.json, packages/nextjs-test-app/tsconfig.json, packages/vue/tsconfig.json, testing/visual-testing/tsconfig.test.json
Selected TypeScript targets and libraries are updated from ES2017 to ES2020.

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

Suggested reviewers: danielleroux

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and matches the accessibility-focused dropdown-button-icon changes, though it does not cover the full multi-package scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@changeset-bot

changeset-bot Bot commented Jul 15, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 1e06d47

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@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 layout adjustments to dropdown buttons, updates TypeScript configurations to target ES2020, and changes the EMPTY_PROP sentinel from a Symbol to an object literal in Vue utilities, accompanied by a patch for @stencil/vue-output-target. Feedback on these changes advises against using patch-package in a pnpm workspace to avoid global store corruption, recommending pnpm's native patching mechanism instead. Additionally, it is recommended to freeze the newly defined EMPTY_PROP object using Object.freeze() to prevent accidental mutations.

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 package.json Outdated
Comment on lines +33 to +34
"prepare": "pnpm disable-telemetry && patch-package --patch-dir patches --patch-content-hash",
"postinstall": "patch-package --patch-dir patches --patch-content-hash",

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

Using patch-package in a pnpm workspace is highly discouraged and can lead to issues. Since pnpm uses a global content-addressable store and hard links files into node_modules, running patch-package can directly modify files in the global store, potentially corrupting it for other projects on the same machine. Additionally, it may not apply reliably due to pnpm's symlink structure.

Instead, use pnpm's native patching mechanism:

  1. Run pnpm patch @stencil/vue-output-target to extract the package to a temporary directory.
  2. Make the required changes in that directory.
  3. Run pnpm patch-commit <temp-dir> to generate the patch file and automatically configure it under patchedDependencies in your configuration file (e.g., pnpm-workspace.yaml or package.json depending on your pnpm version).
  4. Remove patch-package and postinstall-postinstall from your devDependencies.
Suggested change
"prepare": "pnpm disable-telemetry && patch-package --patch-dir patches --patch-content-hash",
"postinstall": "patch-package --patch-dir patches --patch-content-hash",
"prepare": "pnpm disable-telemetry",

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I've migrated away from patch-package to pnpm's native patching mechanism to stay consistent with the existing @stencil/core patch and avoid the content-addressable store risks you mentioned.

* See https://github.com/vuejs/vue-next/issues/3889
*/
const EMPTY_PROP = Symbol();
const EMPTY_PROP = {};

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.

medium

Since EMPTY_PROP is now defined as a plain object {} instead of a unique Symbol(), it is mutable. To prevent accidental mutation of this sentinel value elsewhere in the codebase, it is highly recommended to freeze the object using Object.freeze().

Suggested change
const EMPTY_PROP = {};
const EMPTY_PROP = Object.freeze({});

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[EMPTY_PROP] is only used as a sentinel compared by reference equality [value !== EMPTY_PROP] and is never mutated anywhere, so freezing isn't functionally required. I've left it as a plain {} for now to keep the patch minimal and aligned with the upstream source.

@sonarqubecloud

Copy link
Copy Markdown

@GayatriK2002
GayatriK2002 marked this pull request as ready for review July 17, 2026 04:44

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/vue/src/vue-component-lib/utils.ts`:
- Around line 185-191: Add regression tests around the prop-forwarding logic
containing ARIA_PROP_PREFIX and EMPTY_PROP, covering omitted ARIA props being
excluded rather than passed as the sentinel string and explicit values such as
aria-label="Menu" being forwarded unchanged. Exercise the actual Vue runtime
path and the utility implementation when both are shipped.

In `@pnpm-workspace.yaml`:
- Line 28: Add a changeset describing the Vue wrapper accessibility behavior
change and identifying the affected package with the appropriate release bump;
do not treat the patch entry for `@stencil/vue-output-target` as sufficient
release documentation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 838d2ba2-7313-40e3-9e51-913f4aa4a83c

📥 Commits

Reviewing files that changed from the base of the PR and between 1eee43f and 1e06d47.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • packages/angular-standalone-test-app/src/preview-examples/dropdown-button.css
  • packages/angular-test-app/src/preview-examples/dropdown-button.css
  • packages/angular/tsconfig.json
  • packages/html-test-app/src/preview-examples/dropdown-button.css
  • packages/nextjs-test-app/tsconfig.json
  • packages/react-test-app/src/preview-examples/dropdown-button.scoped.css
  • packages/vue-test-app/src/preview-examples/dropdown-button-icon.vue
  • packages/vue-test-app/src/preview-examples/dropdown-button.css
  • packages/vue-test-app/src/preview-examples/dropdown-button.vue
  • packages/vue/src/vue-component-lib/utils.ts
  • packages/vue/tsconfig.json
  • patches/@stencil__vue-output-target.patch
  • pnpm-workspace.yaml
  • testing/visual-testing/tsconfig.test.json

Comment on lines 185 to 191
if (
// eslint-disable-next-line no-prototype-builtins
(props.hasOwnProperty(key) && value !== EMPTY_PROP) ||
key.startsWith(ARIA_PROP_PREFIX)
(key.startsWith(ARIA_PROP_PREFIX) && value !== EMPTY_PROP)
) {
propsToAdd[key] = value;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Add regression coverage for sentinel-valued and explicit ARIA props.

Test that omitted ARIA props never reach the custom element as a sentinel string, while explicit values such as aria-label="Menu" are still forwarded unchanged. Exercise the actual Vue runtime path as well as this utility if both implementations are shipped.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/vue/src/vue-component-lib/utils.ts` around lines 185 - 191, Add
regression tests around the prop-forwarding logic containing ARIA_PROP_PREFIX
and EMPTY_PROP, covering omitted ARIA props being excluded rather than passed as
the sentinel string and explicit values such as aria-label="Menu" being
forwarded unchanged. Exercise the actual Vue runtime path and the utility
implementation when both are shipped.

Comment thread pnpm-workspace.yaml

patchedDependencies:
'@stencil/core': "patches/@stencil__core.patch"
'@stencil/vue-output-target': "patches/@stencil__vue-output-target.patch"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add a changeset for this accessibility behavior change.

This PR changes Vue wrapper behavior and user-facing accessibility output. Add a changeset for the affected package, or explicitly justify in the PR why the change is internal-only.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pnpm-workspace.yaml` at line 28, Add a changeset describing the Vue wrapper
accessibility behavior change and identifying the affected package with the
appropriate release bump; do not treat the patch entry for
`@stencil/vue-output-target` as sufficient release documentation.

Source: Path instructions

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