Import page: Owner/Name row misaligned — apply the #497 New-repo fix identically (matched heights, aligned labels, narrower Owner column) #499

Closed
opened 2026-09-13 21:36:15 +00:00 by crueber · 1 comment
Owner

What's requested

On the Import repository page, the Owner select and Name input sit side-by-side in a 50/50 sm:grid-cols-2 grid, and the pair is visibly misaligned — the same defect just filed for the New repository page (#497). Apply the identical fix to Import: matched control heights, aligned labels, and a narrower Owner column. #497 is the reference implementation — same classes/component on both pages, no divergence.

Prescribe a matched pair (identical to #497's fix):

  1. Matched heights — Owner select and Name input must render the same control height and share a common baseline across the row. Normalize explicitly (shared height utility on both, or appearance-none styling on the select) rather than relying on the .input class alone, since native <select> vs <input> render a few px apart in some browsers.
  2. Aligned labels — the "Owner" and "Name" labels sit on one line at the same size/weight; Name's reserved error slot (min-h-[2rem], aria-live) must not affect the sibling column's geometry (error text outside the two-column grid row, or items-start on the grid so the controls stay top-aligned).
  3. Narrower Owner column — Owner holds a bounded list (self + member orgs via allowedOwners); use the same asymmetric split #497 lands (e.g. sm:grid-cols-[minmax(0,1fr)_minmax(0,2fr)], exact ratio implementer's call), with minmax(0, …) so long owner names truncate instead of blowing the column.

Evidence (static read of current tree, commit b3544e5)

  • web/src/pages/Import.jsx:281-321 — the row: <div class="grid grid-cols-1 gap-3 sm:grid-cols-2"> wrapping:
    • Owner label (Import.jsx:282-302): <label class="grid gap-1"> + <select id="import-owner" class="input font-mono"> (disabled fallback select while owners load). No sub-text.
    • Name label (Import.jsx:303-320): same shape plus <p id="import-name-error" class="min-h-[2rem] …"> inside the label — a 2rem-tall block only the Name column has, so the two grid columns have unequal intrinsic heights.
  • web/src/pages/New.jsx:147-186 — the New page row is copy-paste-identical (except new-owner/new-name ids). This ticket's fix must be whatever #497 lands, applied here; if #497's fix extracts a shared component, consume it here rather than re-duplicating.
  • web/src/ui.css:120-123 — .input is w-full px-2.5 py-1.5 text-sm; it styles both controls but pins nothing about select-vs-input rendered height, which is the height-match gap on this page too.

Architecture notes

  • This is the same markup verbatim as #497 (import-owner/import-name vs new-owner/new-name). The fix is intentionally identical: if #497 is implemented as shared classes, mirror them exactly; if it extracts a shared Owner/Name field component, Import consumes the same component.
  • validateRepoChars live validation (#486) and the mirror-mode error path (validateMirrorCreate) are unaffected — only the row's layout changes; the error slot's aria-live and aria-describedby wiring stays.
  • The Import page also has the Source URL field above (full-width) and Token below; neither participates in the two-column row — don't disturb them.

Acceptance criteria

  • On /import, Owner select and Name input are the same rendered height and top-aligned; their labels sit on one shared baseline.
  • The Name error slot does not change the Owner column's height or position; charset validation errors still render in place with aria-live intact.
  • Owner column is narrower than Name column at sm: and up with the same ratio as #497's fix; long owner names truncate/ellipsis rather than stretching the column; mobile single-column stack still works.
  • /import and /new use identical classes (or the same shared component) — no drift between the two pages.
  • Owner select keyboard/a11y behavior unchanged (aria-label, disabled loading fallback intact); Import's Source URL and Token fields unaffected.
## What's requested On the **Import repository** page, the **Owner** select and **Name** input sit side-by-side in a 50/50 `sm:grid-cols-2` grid, and the pair is visibly misaligned — the same defect just filed for the New repository page (#497). Apply the identical fix to Import: matched control heights, aligned labels, and a narrower Owner column. **#497 is the reference implementation — same classes/component on both pages, no divergence.** Prescribe a matched pair (identical to #497's fix): 1. **Matched heights** — Owner select and Name input must render the same control height and share a common baseline across the row. Normalize explicitly (shared height utility on both, or `appearance-none` styling on the select) rather than relying on the `.input` class alone, since native `<select>` vs `<input>` render a few px apart in some browsers. 2. **Aligned labels** — the "Owner" and "Name" labels sit on one line at the same size/weight; Name's reserved error slot (`min-h-[2rem]`, aria-live) must not affect the sibling column's geometry (error text outside the two-column grid row, or `items-start` on the grid so the controls stay top-aligned). 3. **Narrower Owner column** — Owner holds a bounded list (self + member orgs via `allowedOwners`); use the same asymmetric split #497 lands (e.g. `sm:grid-cols-[minmax(0,1fr)_minmax(0,2fr)]`, exact ratio implementer's call), with `minmax(0, …)` so long owner names truncate instead of blowing the column. ## Evidence (static read of current tree, commit b3544e5) - `web/src/pages/Import.jsx:281-321` — the row: `<div class="grid grid-cols-1 gap-3 sm:grid-cols-2">` wrapping: - Owner label (`Import.jsx:282-302`): `<label class="grid gap-1">` + `<select id="import-owner" class="input font-mono">` (disabled fallback select while owners load). No sub-text. - Name label (`Import.jsx:303-320`): same shape plus `<p id="import-name-error" class="min-h-[2rem] …">` **inside** the label — a 2rem-tall block only the Name column has, so the two grid columns have unequal intrinsic heights. - `web/src/pages/New.jsx:147-186` — the New page row is copy-paste-identical (except `new-owner`/`new-name` ids). This ticket's fix must be whatever #497 lands, applied here; if #497's fix extracts a shared component, consume it here rather than re-duplicating. - `web/src/ui.css:120-123` — `.input` is `w-full px-2.5 py-1.5 text-sm`; it styles both controls but pins nothing about select-vs-input rendered height, which is the height-match gap on this page too. ## Architecture notes - This is the same markup verbatim as #497 (`import-owner`/`import-name` vs `new-owner`/`new-name`). The fix is intentionally identical: if #497 is implemented as shared classes, mirror them exactly; if it extracts a shared Owner/Name field component, Import consumes the same component. - `validateRepoChars` live validation (#486) and the mirror-mode error path (`validateMirrorCreate`) are unaffected — only the row's layout changes; the error slot's `aria-live` and `aria-describedby` wiring stays. - The Import page also has the Source URL field above (full-width) and Token below; neither participates in the two-column row — don't disturb them. ## Acceptance criteria - [ ] On `/import`, Owner select and Name input are the same rendered height and top-aligned; their labels sit on one shared baseline. - [ ] The Name error slot does not change the Owner column's height or position; charset validation errors still render in place with `aria-live` intact. - [ ] Owner column is narrower than Name column at `sm:` and up with the **same ratio as #497's fix**; long owner names truncate/ellipsis rather than stretching the column; mobile single-column stack still works. - [ ] `/import` and `/new` use identical classes (or the same shared component) — no drift between the two pages. - [ ] Owner select keyboard/a11y behavior unchanged (`aria-label`, disabled loading fallback intact); Import's Source URL and Token fields unaffected.
crueber added this to the v1 milestone 2026-09-13 21:36:26 +00:00
Author
Owner

Already satisfied by #497 (PR #500): Import.jsx:286 renders the shared OwnerNameRow with identical props to New.jsx:152 (prefix/placeholder only differ) — matched heights, below-grid error slot, asymmetric split, and live validation all come along by construction. No separate change needed. Closing.

Already satisfied by #497 (PR #500): Import.jsx:286 renders the shared OwnerNameRow with identical props to New.jsx:152 (prefix/placeholder only differ) — matched heights, below-grid error slot, asymmetric split, and live validation all come along by construction. No separate change needed. Closing.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
crueber/walhub#499
No description provided.