[ui5-dynamic-side-content]: accessibilityAttributes role "none"/"presentation" cannot remove the landmark because aria-label is always applied

Đang mở Phù hợp với người mới
#14,244 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 3 ngày

@GDamyanov đang làm issue này rồi.

Từ ngày 2/11/2026.

  • #14247 của @GDamyanov — đang mở

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
80/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
html, typescript
Lĩnh vực
accessibility, frontend

Hướng nghiên cứu

Bắt đầu trong packages/fiori/src/DynamicSideContent.ts, trong getter accInfo nơi sideContent và vùng chứa chính xây dựng ariaLabel và role; lưu ý các fallback i18n DSC_SIDE_ARIA_LABEL và DSC_MAIN_ARIA_LABEL. Giải quyết role trước, sau đó bỏ ariaLabel (và fallback i18n) khi role đó là none, presentation hoặc undefined, cho cả hai vùng chứa. Hoàn thành nghĩa là <aside> được render không mang aria-label khi role: "none" được đặt và cây trợ năng không còn hiển thị landmark complementary lồng nhau, được xác minh dựa trên các bài kiểm thử DynamicSideContent hiện có.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Bug Description

Follow-up to #13013 / PR #13476.

#13013 requested customizable ARIA roles for ui5-dynamic-side-content so it can be nested inside a page that already has a main landmark. PR #13476 added a role field to accessibilityAttributes and #13013 was closed as resolved.

However, the new role option cannot actually remove the landmark on the side (or main) container, so the original APG violation still occurs. Setting sideContent.role to "none"/"presentation" has no effect on the exposed landmark, because the component unconditionally applies a non-empty aria-label to the same element. Per the WAI-ARIA Presentational Roles Conflict Resolution, a role="none"/"presentation" element that also carries a global ARIA property such as aria-label has its presentational role ignored and its implicit role restored — so <aside> reverts to complementary.

Affected Component

ui5-dynamic-side-content

Expected Behaviour

When the resolved role of the main/side container is "none", "presentation", or undefined, the container should not be exposed as a landmark. Concretely, in that case the component should omit the container's aria-label (and skip the DSC_MAIN_ARIA_LABEL / DSC_SIDE_ARIA_LABEL i18n fallback), so that role="none" actually takes effect.

Isolated Example

No StackBlitz; the issue reproduces with plain markup (the web component renders exactly this into its shadow DOM). Minimal repro:

<main>
  <aside role="none" aria-label="Side Content">
    <div role="region" aria-label="Filter Panel">Filters</div>
  </aside>
</main>
Steps to Reproduce
  1. Render a ui5-dynamic-side-content inside a page that already exposes a main landmark.
  2. Set accessibilityAttributes = { sideContent: { role: "none" } } (or { role: undefined }).
  3. Inspect the computed accessibility tree (Chrome DevTools → Elements → Accessibility, or a screen reader's landmark list).
  4. Observe the side container is still exposed as a complementary landmark nested inside main.
Log Output, Stack Trace or Screenshots

Rendered side container (shadow DOM):

<aside role="none" aria-label="Side Content" class="ui5-dsc-side">…</aside>

Computed accessibility tree — landmark is still present, nested in main:

main
  complementary "Side Content"
    region "Filter Panel"

The only state that actually drops the landmark is role="none" with no aria-label:

main
  region "Filter Panel"      ← complementary gone, child region preserved

role: undefined does not help either: it only removes the role attribute, and a bare <aside> with an accessible name is still an implicit complementary landmark.

Priority

High

Environment Info

UI5 Web Components Version

@ui5/webcomponents-fiori 2.25.x (reproduced; accInfo unchanged on main as of filing)

Browser

Chrome

Operating System

macOS

Additional Info

Additional Context

Root cause — in accInfo (packages/fiori/src/DynamicSideContent.ts):

sideContent: {
  ariaLabel: sideContentAttr.ariaLabel || DynamicSideContent.i18nBundle.getText(DSC_SIDE_ARIA_LABEL),
  role: hasSideRole ? sideContentAttr.role : "complementary",
},

The role line is correct — passing role: "none" yields role="none" on the <aside>. The problem is the ariaLabel line above it: it is always truthy (falls back to the i18n default), and no prop value can blank it, so the presentational role is always nullified by conflict resolution.

Suggested fix (side shown; same for main):

const sideRole = hasSideRole ? sideContentAttr.role : "complementary";
const sidePresentational = sideRole === "none" || sideRole === "presentation" || sideRole === undefined;

sideContent: {
  ariaLabel: sidePresentational
    ? undefined
    : (sideContentAttr.ariaLabel || DynamicSideContent.i18nBundle.getText(DSC_SIDE_ARIA_LABEL)),
  role: sideRole,
},

Business impact — the SuccessFactors shell renders role="main" on the page content area, so any embedded DynamicSideContent produces a complementary (and previously a second main) landmark nested inside main — a WAI-ARIA APG violation flagged in accessibility audits. The role property from #13476 is the intended mitigation but cannot take effect while the aria-label is forced.

cc @DMihaylova — follow-up to #13013, since PR #13476 does not fully resolve it.

Organization

SAP-SF

Declaration
  • I’m not disclosing any internal or sensitive information.
Ngôn ngữ chính
TypeScript
Star
1.8k
Fork
290
Merge trung bình
3 ngày 12 giờ
Pull request đã merge (30 ngày)
54

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của UI5/webcomponents

Tất cả issue của UI5/webcomponents

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.