Skip to content

bug/refactor(ui): focus-visible outline classes are not applied and should be standardized via component utilities #329

Description

@KaiUweCZE

Problem

Some UI components currently use long arbitrary Tailwind classes for focus-visible outline behavior (for example, data-focus-visible:outline-(style:--default-ring-style)).

This creates three issues:

  • poor readability and maintainability in component TSX class lists,
  • inconsistent naming across components,
  • and in at least some cases the class does not get applied as expected (for example data-focus-visible:outline-(style:--default-ring-style)).

Goal

Use consistent, readable, and reliable focus utility classes defined in component token files (tokens/components/**/_<component>.css) instead of arbitrary outline expressions in TSX.

Decision

  • Do not use focus-visible arbitrary outline patterns in TSX:
    • outline-(style:...)
    • outline-(length:...)
    • outline-offset-(length:...)
  • Define component-scoped utility classes in _component.css following naming conventions:
    • outline-<component>-focus-style
    • outline-<component>-focus-width
    • outline-<component>-focus-ring
    • outline-<component>-focus-offset
  • Use only those utilities from component TSX.

Example (Combobox)

Before:

  • data-focus-visible:outline-(style:--default-ring-style)
  • data-focus-visible:outline-(length:--default-ring-width)
  • data-focus-visible:outline-combobox-ring
  • data-focus-visible:outline-offset-(length:--default-ring-offset)

After:

  • data-focus-visible:outline-combobox-focus-style
  • data-focus-visible:outline-combobox-focus-width
  • data-focus-visible:outline-combobox-focus-ring
  • data-focus-visible:outline-combobox-focus-offset

Acceptance Criteria

  • No focus-visible arbitrary outline patterns above remain in libs/ui/src/**/*.tsx.
  • Each migrated component has equivalent focus utility classes in its own _component.css token file.
  • Storybook keyboard testing confirms focus-visible style/width/ring/offset are actually applied.
  • Naming is consistent across components.

Notes

This is a cross-component refactor and should be implemented in a dedicated follow-up branch after the current PR is merged.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions