Skip to content

[Dropdown]: DropdownTriggerDirective breaks a checkbox host #669

Open

Description

@ceisipeik

Problem

DropdownTriggerDirective (dropdown-trigger.directive.ts) assumes the trigger is a <button> or <a href>.

For every other host element it sets role="button" and tabindex="0", onKeydown handles only ArrowDown, ArrowUp and Escape; opening with Enter relies on the host element firing a native click event on Enter.

With <input tedi-checkbox tedi-dropdown-trigger type="checkbox"> (a "select all" header checkbox that opens a menu with "select page" / "select all" / "clear") this produces two defects:

  1. Enter does not open the dropdown: a checkbox does not fire click on Enter, and the directive does not handle the key.
  2. The checkbox loses its semantics: because <input type="checkbox"> is not a <button> or <a href>, the directive adds role="button" and tabindex="0" to the checkbox element at runtime. The added role="button" overrides the native checkbox role, so assistive technology reports the element as a button and no longer announces its checked and indeterminate state.

The consuming project currently adds its own (keydown.enter) handler on the checkbox and accepts that the checked state is not announced.

Examples and information

<tedi-dropdown>
  <input tedi-checkbox tedi-dropdown-trigger type="checkbox"
         [checked]="allSelected()" [indeterminate]="someSelected()"
         ariaLabel="Select rows" (click)="$event.preventDefault()" />
  <tedi-dropdown-content dropdownRole="menu">
    <li tedi-dropdown-item>Select page</li>
    <li tedi-dropdown-item>Select all</li>
  </tedi-dropdown-content>
</tedi-dropdown>

Expected: Tab to the checkbox, screen reader announces "checkbox, mixed"; Enter opens the menu.
Actual (8.0.0): announced as "button"; Enter does nothing.

Project

SFOS

DoD

  • The component is developed using best practices, conventions, and modern frontend trends
  • The component follows BEM naming conventions (if applicable)
  • The component implementation matches the Figma design, including all defined states and interactions
  • The component supports responsiveness and scales across breakpoints (if applicable)
  • The component does not introduce runtime errors or warnings
  • Linter passes
  • The component is exported from its tier barrel
  • The component has unit tests with at least 80% code coverage (enforced by the global Jest coverageThreshold over tedi/components, not per component)
  • CodeCov passes its threshold (80% on the changed code, with 10% tolerance — a separate gate from the Jest one above)
  • The component has passed code review
  • The component has passed Chromatic visual review
  • Storybook stories are created:
    • Cover all Figma variations
    • Include edge cases, empty/error states
  • Component’s API (props, slots, events) is documented
  • ZeroHeight is updated with design/development guidelines
  • External dependencies used in the component are documented in Storybook and Zeroheight, with rationale
  • Semantic commit format type(scope): Subject text #issue-ref is used (for semantic-release), with the issue reference required - see Commit convention
  • External libraries comply with validated open source licenses
  • Component is versioned correctly and ready for release if required
  • Update the Angular development status on the statuses page in Zeroheight
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

tedi-readyTEDI-Ready component issue

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions