Accessibility

ACR / VPAT-style

Accessibility Conformance Report for team and enterprise buyers evaluating Ply. Standard: WCAG 2.2 Level AA. Product: Ply (ply-ui-cli) + ply-ui.com demo. Report date: 2026-09-13.

Honest living report — not a full WCAG certification claim. Core free primitives are covered by axe-core in CI. Gaps below are listed so compliance reviewers can scope residual risk.

Evaluation methods

  • Automated: axe-core WCAG 2.x A/AA rules on a free-primitives smoke host plus open overlays (combobox, dialog, dropdown, menubar) in the library Vitest suite (color-contrast disabled under jsdom; verified in product themes).
  • Manual: keyboard paths for dialogs (focus trap), menus (roving tabindex and typeahead via a11y-keyboard), combobox/select (aria-activedescendant), menubar arrows, data-table sort/row keys, mega-menu disclosure (ArrowDown/Escape), and datepicker popups (Escape, focus into the calendar grid). Flagship demos also publish a Keyboard & accessibility section (roles, focus, shortcuts) next to the component — Button, Dialog, Calendar, and others. This ACR is the procurement summary; those notes are the component-level detail.
  • Product: class-based dark mode, semantic HTML wrappers for buttons/inputs, CDK a11y for overlays.

WCAG 2.2 conformance summary

WCAG 2.2 criteria with conformance level and remarks for Ply
CriterionNameLevelConformanceRemarks
1.1.1 Non-text ContentA Partially Supports Icons support aria-hidden / decorative use; some marketing and layout demos still rely on visual-only cues.
1.3.1 Info and RelationshipsA Partially Supports Form labels, alerts, and progress expose roles/relationships; coverage varies across Pro blocks and layouts.
1.3.2 Meaningful SequenceA Supports DOM order matches visual reading order. dir="rtl" on html, or plyDir on a section, flips layout, icons, overlays, and horizontal keyboard order. See /configuration/#rtl.
1.4.1 Use of ColorA Partially Supports Status colors are paired with text or icons in core primitives; not audited for every Pro block.
1.4.3 Contrast (Minimum)AA Partially Supports Default slate/blue palettes target AA in light and dark themes. Consumer brand overrides are their responsibility.
1.4.10 ReflowAA Partially Supports Primitives reflow with Tailwind utilities; complex Pro layouts may require consumer tuning at 320px.
1.4.13 Content on Hover or FocusAA Partially Supports Tooltips and menus are dismissible; not every overlay pattern is exhaustively tested.
2.1.1 KeyboardA Partially Supports Dialogs trap focus (CDK FocusTrap) and take their accessible name from the heading after content is inserted. Dropdown and context menus share a11y-keyboard (roving tabindex, Home/End, typeahead). Combobox, custom-select, and command-palette use aria-activedescendant. Axe-core in CI opens combobox, dropdown menu, menubar, and dialog. Data-table key specs are Enter and Space. The dialog Escape spec calls onEscape() rather than dispatching a key.
2.1.2 No Keyboard TrapA Supports Modal dialogs restore focus on close; Escape dismisses supported overlays.
2.2.2 Pause, Stop, HideA Partially Supports Ripple, reveal, hero motion, and toasts respect prefers-reduced-motion. Toast auto-dismiss pauses while the stack is hovered or focused. Library-wide reduced-motion coverage is still expanding.
2.4.3 Focus OrderA Supports Focus order follows DOM order for documented component compositions.
2.4.7 Focus VisibleAA Partially Supports Interactive primitives use visible focus rings; some Pro chrome still needs audit.
2.5.8 Target Size (Minimum)AA Partially Supports Default control heights (e.g. h-9 inputs/buttons) meet 24×24px; dense icon-only controls may need consumer padding.
3.2.4 Consistent IdentificationAA Supports Shared ply-* selectors and patterns across the library.
3.3.1 Error IdentificationA Partially Supports ply-error and alert patterns exist; wiring to aria-describedby is consumer-owned in forms.
3.3.2 Labels or InstructionsA Partially Supports ply-label projects with inputs; composite controls document labeling in demos.
4.1.2 Name, Role, ValueA Partially Supports ~40% of templates declare aria-* today. Progress, toggles, dialogs, and menus expose roles; remaining gaps are tracked in CI via axe (closed primitives and open overlays).
4.1.3 Status MessagesAA Partially Supports Alerts and toasts communicate status; live-region usage is not universal yet.

Writing direction

Set dir="rtl" on <html>, or plyDir="rtl" on a section. Layout, directional icons, overlays, drawers, and horizontal keyboard order follow that direction. Explicit left and right placements stay on those physical edges. Setup and the plyDir API.

Known gaps (roadmap)

prefers-reduced-motion

Honored in ripple, reveal, hero-features, and toast (static list, no swipe tween). Broader animation inventory still being wired.

a11y-keyboard adoption

Roving-focus helper (including typeahead) is used by dropdown-menu and context-menu. Combobox, custom-select, and command-palette correctly use aria-activedescendant instead of that helper. Mega-menu is a disclosure navigation, not a menuitem list — ArrowDown/Escape and panel-link arrows are covered by specs. Datepicker and date-range-picker popups close on Escape and move focus into the calendar grid. showTime keeps that grid, then a clock step, in the same popup.

Continuous testing

Every library CI run executes the axe smoke suite:

npx ng test Base --watch=false --include='**/a11y.smoke.spec.ts'

Helper: projects/base/src/lib/testing/a11y.ts (expectNoA11yViolations). Questions for team licenses or a signed PDF ACR: [email protected].