fix(ui): keep dialog action rows on one line (#1762)

* fix(ui): keep dialog action rows on one line

Settings "Unsaved changes" dialog:
- Cancel / Discard / Save replace the phrase labels in all 19 locales, and
  the dismiss now comes first; the shared CANCEL key replaces the unused
  UNSAVED_DIALOG_STAY.
- At the 640px phone breakpoint the actions stack one per row, full width,
  in DOM order.

EPG programme dialog:
- mat-dialog-title gives the dialog an accessible name.
- The footer Close is the only dismiss; it comes first and the primary
  action last.
- The archive copy/download tools move under their notice, so the footer
  stays on one row.
- Channel rows now open it through EpgProgrammeDialogService, which owns
  the 540px config and a panel class scoping the surface overrides.

Adds a web-e2e layout spec (en, de, ru, fr, hu, ar on one row; de and ru
stacked on a phone), extends the Electron EPG spec to all three openers,
and documents the dialog contract in the UI guidelines.

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

* fix(epg): stack programme dialog actions on phones

Below the 640px phone breakpoint the viewport caps the programme dialog,
and a long translated primary label ("Regarder depuis le début") no
longer fit beside Close. The footer had no wrap, and the dialog hides
overflow, so the label was clipped.

- At the phone breakpoint, the archive tools and the footer now stack one
  full-width button per row, in DOM order.
- Buttons grow to fit their label, so a long label wraps inside its
  button instead of being clipped.
- On desktop the footer can wrap again as a last resort.

The new Electron test opens a past programme in French at a 360px
viewport and measures both rows. It fails against the previous
stylesheet (the footer buttons are 44px narrower than the row).

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-09-30 21:54:09 +02:00
1 parent d4118ad442
commit cb317bad4c
31 files changed
+853 -187

No files matched your search

@@ -652,6 +652,34 @@ Settings use the same system but are flatter than content-heavy views.
- Neutral rows can use low-opacity dark overlays
- Keep strong blue tint reserved for active sections and selected items
## Dialogs
- **Name.** Every dialog has a `mat-dialog-title`; Material points the
container's `aria-labelledby` at it. A custom-styled title keeps the
directive and overrides Material's headline padding and 40px `::before`
strut, as the programme dialog does.
- **Order.** Dismiss first, primary last. With end alignment the primary sits
on the inline end: the right in LTR, the left in RTL.
- **One dismiss.** Offer one visible dismiss: a footer "Cancel"/"Close" or a
header close icon, not both. Escape and the backdrop still close.
- **One row.** Action labels are short verbs ("Cancel", "Discard", "Save"),
not phrases, so the row fits one line in every locale at the dialog width.
Secondary actions tied to one part of the content stay with that content
(the programme dialog's archive tools sit under their notice), so the
footer is only the dismiss and the primary.
- **Phone.** At the phone breakpoint an action row may stack: one full-width
button per row, in DOM order (dismiss on top, primary at the bottom). The
settings unsaved-changes dialog is the reference;
`settings-unsaved-dialog-layout.e2e.ts` in `web-e2e` measures it in six
locales. The programme dialog stacks its archive tools and footer the same
way, letting a long label wrap inside its button; the Electron
`epg-timeline-interaction.e2e.ts` measures it in French at 360px.
- **Width.** A dialog with several openers is opened through one helper that
owns its `MatDialogConfig`, so its width never depends on the entry point.
`EpgProgrammeDialogService` opens the programme dialog at 540px from the
timeline, list, guide and channel rows, with a panel class that scopes its
surface overrides.
## Phone Layout
`640px` is the phone breakpoint. Use `@media (max-width: 640px)` rather than