fix(catalog): short sort chip label and radio sort menus (#1881)

* fix(catalog): short sort chip label and radio sort menus

The catalog sort chip now shows one short label per mode at every width
("Newest", "A-Z", "Top rated") and keeps the full "Sort: ..." text in its
aria-label, so it no longer truncates in long translations. The rating
chip follows the same rule and puts its clear icon after the value. The
1120px container query that swapped full and compact labels is gone.

Single-choice mat-menus get a shared appMenuItemRadio /
appMenuItemRadioCheck pair: rows are menuitemradio with aria-checked, and
every row reserves a leading check slot that is visible only when
checked. Material projects every mat-icon ahead of the label, so the old
check rendered only on the chosen row shifted that row's label. Applied
to the catalog refine menu (sort and rating groups), Xtream live
channels, M3U all channels and groups, unified collection favorites,
workspace categories and workspace sources.

Adds WORKSPACE.SORT_CHIP keys in all locales and drops the unused
WORKSPACE.FILTER_RATING key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(catalog): read the full sort to screen readers from hidden text

A plain div cannot carry an accessible name, so screen readers could skip
the chip's aria-label and read only the short "Newest". The full
"Sort: ..." text now sits in a visually hidden span and the short label
is aria-hidden; the polite live region announces the full text on change.
The spec checks the text outside aria-hidden, and the E2E checks the
chip's accessibility tree in en, de, ru and hu.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Opus 5.5 authored and GitHub committed 2026-10-10 23:20:42 +02:00
1 parent 039238b7bc
commit ea515280e3
50 files changed
+1177 -249

No files matched your search

@@ -153,6 +153,45 @@ Use this pattern for:
Do not add extra badges, left rails, or second selection systems unless there is a strong reason.
## Single-Choice Menus And Status Chips
A `mat-menu` that picks one value, such as a sort order or a rating
threshold, uses `appMenuItemRadio` and `appMenuItemRadioCheck` from
`@iptvnator/ui/components`:
```html
<button mat-menu-item [appMenuItemRadio]="mode() === option.mode">
<mat-icon appMenuItemRadioCheck>check</mat-icon>
<mat-icon>{{ option.icon }}</mat-icon>
<span>{{ option.labelKey | translate }}</span>
</button>
```
- The row becomes a `menuitemradio` whose `aria-checked` follows the bound
state, so E2E tests select it with `getByRole('menuitemradio')`.
- Every row renders the check slot as its first icon. Only the checked row
shows it. Material projects every `<mat-icon>` of a menu item, and of a
`mat-button`, ahead of the label. A check rendered only on the chosen row
therefore shifted that row's label. In a button, put a trailing icon after
the label with `iconPositionEnd`.
- A semantic icon, if any, comes after the check slot.
- A menu with several groups, such as the catalog refine menu, wraps each
group in `role="group"`. The group is named by its section title, and
`role="separator"` sits between groups.
A chip that shows the active state next to its menu trigger, such as the
catalog sort chip, shows its icon and a short value at every width, for
example "Newest" or "9.0+". Do not swap between a full and a compact label
with container queries: long translations still cut off the full label.
Screen readers must still get the full text, such as "Sort: Date Added
(Latest First)":
- A chip that is a button carries it in `aria-label`.
- A plain `div` chip cannot be named, and screen readers may ignore its
`aria-label`. Put the full text in a `.visually-hidden` span and mark the
short label `aria-hidden="true"`.
## Detail Views
VOD and series detail screens share `app-portal-detail-shell` and