From 680b9a1308d5c358c5ec79d3029c0d86d6f781ab Mon Sep 17 00:00:00 2001 From: Florian Sylvain Date: Tue, 3 Nov 2026 04:24:44 +0100 Subject: [PATCH] feat: article editor header redesign --- docs/design/components.md | 2 +- docs/design/localization-tables.md | 10 +++++----- docs/design/source/LocaleFrame.dc.html | 11 ++++++----- docs/design/source/locale-spec.js | 10 +++++----- web/src/components/EditorHeader.vue | 18 ++++++++---------- web/src/components/EditorTitleField.vue | 19 +++++++++---------- 6 files changed, 34 insertions(+), 36 deletions(-) diff --git a/docs/design/components.md b/docs/design/components.md index 03113c9..f20260e 100644 --- a/docs/design/components.md +++ b/docs/design/components.md @@ -175,7 +175,7 @@ Specs: field heights 40 (44 mobile), buttons 36 (44 mobile), card padding 16, se | LanguageMenu | UDropdownMenu with a UButton trigger | Menu button with menu; rows carry badges and a Read only tag; no Add translation row without create permission | | CapabilityGate | none (logic) | Renders each action from capabilities[]; never from the role name | | EditorHeader | UButton, UBadge, UDropdownMenu | Title row, then language, badges and actions. At most one filled button. Collapse order and mobile bottom bar in the header priority table | -| TitleInput | UInput (heading size) | Label "Title (French)"; bounds 3 to 200; counter; helper under the field | +| TitleInput | UInput (heading size) | Accessible name "Title (French)", no visible label, underline style; bounds 3 to 200; counter; helper under the field | | ActionOverflow | UDropdownMenu (desktop), UDrawer (mobile) | Disabled items carry a visible reason | | StatusBadge | UBadge variant soft | Publication: solid icon plus word | | FreshnessBadge | UBadge variant outline | Refresh icon plus word; icon-only at 1024 with aria-label | diff --git a/docs/design/localization-tables.md b/docs/design/localization-tables.md index 5a8cb69..d0ff52b 100644 --- a/docs/design/localization-tables.md +++ b/docs/design/localization-tables.md @@ -36,7 +36,7 @@ Generated from `source/locale-spec.js`. Read `localization.md` first: its explic | Missing vs hidden | "Not in French" lists stories where French is absent or unreadable to the user. Add French translation on a story with an unreadable French returns a neutral 409 (see Visibility policy) | Discovery cannot leak existence | List | Conflict check ignores read permission; response is neutral | Initial | | Source-copy access | Read access to the chosen source is rechecked at submit, inside the transaction | Access can change while the dialog is open | Add translation | Neutral 403/404 | Initial | | Disabled languages | Versions stay readable and editable; publishing blocked until re-enabled; filter lists them under Disabled | No silent unpublishing | Site languages | enabled flag per site language | Initial | -| Header priority | Left to right: title input (own row), language dropdown, publication badge, status badge (unsaved, saving, saved, failed), freshness badge, Read only tag; then reference button, Unpublish, Save, primary, overflow. At most one filled button. Collapse order: reference label, Unpublish to overflow, freshness to icon | The primary action is never hidden | Editor header | None | Initial | +| Header priority | Left to right: language dropdown, publication badge, status badge (unsaved, saving, saved, failed), freshness badge, Read only tag, title input (fills the remaining width, same row on desktop), then reference button, Unpublish, Save, primary, overflow. At most one filled button. Collapse order: reference label, Unpublish to overflow, freshness to icon | The primary action is never hidden | Editor header | None | Initial | | Public URL pattern | Per-site owner setting with {lang} and {slug}; live preview from a real article; unset state links from "Public URL not configured" | No fabricated website URLs | Settings → Sites | public_url_pattern on site | Initial | | Social locale per language | Per-language owner field on Languages: Derived (from the tag), Set (typed), Not set. Format language_REGION | Never guess a region | Languages page | social_locale per site language | Initial | | Release split | Source reference (L6) and Freshness and review (L9) are release 2. Frames are drawn in full so they can be checked | Smaller first release | None | None | Release 2 | @@ -96,7 +96,7 @@ Generated from `source/locale-spec.js`. Read `localization.md` first: its explic | Control | Accessible name and keyboard | Focus | Announcement | | --- | --- | --- | --- | | Language control | "Language: French. Switch version". Enter or Down opens a menu; arrows move; Enter selects; Escape closes | Into the list on open; back to the control on close | Polite: "Editing French version" | -| Title input | Label "Title (French)"; aria-describedby points to the help or error text; invalid sets aria-invalid and the message is an alert | Stays in the field; on Try again, back to the field | Polite: "Saving title", "Title saved"; errors are announced | +| Title input | Accessible name "Title (French)", no visible label (the language dropdown beside it names the version); aria-describedby points to the help or error text; invalid sets aria-invalid and the message is an alert | Stays in the field; on Try again, back to the field | Polite: "Saving title", "Title saved"; errors are announced | | Save, Save and publish, Retry publish | Buttons named by their text including the language ("Save and publish French"); busy state sets aria-busy; Tab order: title, language, status, reference, Unpublish, Save, primary, More actions | After save, stays on the button; after a failed save, on Try saving again | Polite: "French saved"; "Saved as a draft. Publishing failed. Try publishing again." | | More actions menu or sheet | Menu button "More actions"; items are menuitems; disabled items use aria-disabled and show the reason as text | First enabled item on open; back to More actions on close | None | | Reference button | "Show source reference" or "Hide source reference", icon-only at 1024 with the same name | Moves into the pane on show; back to the button on hide | Polite: "Showing English reference" | @@ -209,7 +209,7 @@ Generated from `source/locale-spec.js`. Read `localization.md` first: its explic | Case | Behavior | | --- | --- | -| Title editing | Inline input in heading style. States: pristine, focus, editing, unsaved, invalid ("Enter a title"), too short, too long, saving, failed (value kept). Bounds 3 to 200 characters. Accessible label "Title (French)". Editing the title never changes the slug | +| Title editing | Inline underline input in heading style, on the same row as the language, badges and actions on desktop (no box, no visible label). States: pristine, focus, editing, unsaved, invalid ("Enter a title"), too short, too long, saving, failed (value kept). Bounds 3 to 200 characters. Accessible label "Title (French)". Editing the title never changes the slug | | Slug | See Slug policy. Edit slug lives in Search and sharing and in the overflow menu; its note says "Editing the title never changes the slug." | | Conflict | "Someone else saved this version at