-
-
I'm not so sure about
.align-items-center.I suspect stretch might be a better option, which would motivate the
.more-infoelement all the way over to the right so that it's out of the way of all of the nav tabs.This would be a much cleaner look because it signifies that the more info button is not part of the nav tabs.
-
@servicedesk please create text-based mock-up diagrams of what the various states would look like visually. Place them in code blocks so that they look neat.
-
{"content": "@zaakiy Here are text mock-ups of the main visual states for the sticky-tabs + more-info docking plan. Legend:
[···]= more-info (ellipsis),|= sticky row edge,==== sticky chrome.\n\n### 1. Default / unscrolled (unchanged)\n\nHeader more-info stays in.card-header. Docked more-info exists in the DOM but is hidden (display: none), so the tabs row looks as it does today.\n\n\n┌──────────────────────────────────────────────────────────────┐\n│ Issues · #1234 · Title of the issue… [···] │ ← card-header\n├──────────────────────────────────────────────────────────────┤\n│ [operations / primary content…] │\n│ │\n│ Activities Commits Builds Files │ ← tabs (not sticky yet)\n│ ───────────────────────────────────────── │\n│ Tab content… │\n│ … │\n└──────────────────────────────────────────────────────────────┘\n\n\n### 2. Today after scroll (problem)\n\nTabs stick; header (and its more-info) scroll away. Side info is unreachable without scrolling back up.\n\n\n┌──────────────────────────────────────────────────────────────┐\n│ Activities Commits Builds Files │ ← sticky tabs\n│ ───────────────────────────────────────── │\n│ Tab content… │\n│ … │\n│ … more scrolled content … │\n│ (no [···] here) │\n└──────────────────────────────────────────────────────────────┘\n\n\n### 3. Proposed sticky / docked —align-items-center\n\nWhen the header trigger leaves the scrollport,.sticky-tabs-rowgets.is-dockedand the docked more-info appears on the right of the sticky row. Withalign-items-center, the control is vertically centered with the tab labels.\n\n\n┌──────────────────────────────────────────────────────────────┐\n│ Activities Commits Builds Files [···] │ ← sticky row\n│ ───────────────────────────────────────── │ dock sits mid-row\n│ Tab content… │\n│ … │\n└──────────────────────────────────────────────────────────────┘\n ↑ tabs grow left ↑ dock (centered)\n\n\n### 4. Side info open\n\nExisting rulebody.side-info-visible a.side-info { display: none }hides both the header and docked triggers. Pane takes the right side.\n\n\n┌────────────────────────────────────────────┬─────────────────┐\n│ Activities Commits Builds Files │ Side info │\n│ ───────────────────────────────────── │ ───────── │\n│ Tab content… │ fields / │\n│ … │ workspaces / │\n│ │ … │\n│ (no [···]) │ [×] │\n└────────────────────────────────────────────┴─────────────────┘\n\n\n### 5. Transition summary\n\n\nunscrolled scroll past header side info open\n─────────── ────────────────── ──────────────\nheader [···] shown header [···] off-screen all a.side-info hidden\ndock hidden dock shown in sticky row pane visible\n\n\nSticky state uses the centered dock in (3) withalign-items-centeron.sticky-tabs-row."} -
@servicedesk my apologies.
3. Proposed sticky / docked — align-items-center (plan as written)is the correct way to go. -
@zaakiy Understood — we'll stick with
align-items-centeron.sticky-tabs-rowas in the plan (mock-up 3). The sticky docked more-info stays vertically centered with the tab labels; no stretch / right-rail layout. -
Please remove option 4 from https://code.onedev.io/onedev/server/~issues/2969#IssueComment-10437
-
@zaakiy Removed option 4 (
align-items-stretch/ right-rail) from the earlier mock-ups and renumbered the remaining states. Sticky state stays withalign-items-centeras confirmed. -
the markdown for the modified comment has been corrupted. Please create a new comment with the text-based mock-up diagrams of what the various states would look like visually. Place them in code blocks so they look neat.
-
@zaakiy Here are the text mock-ups of the main visual states for the sticky-tabs + more-info docking plan (refreshed after the earlier comment markdown corruption). Legend:
[···]= more-info (ellipsis).1. Default / unscrolled (unchanged)
Header more-info stays in
.card-header. Docked more-info exists in the DOM but is hidden (display: none), so the tabs row looks as it does today.┌──────────────────────────────────────────────────────────────┐ │ Issues · #1234 · Title of the issue… [···] │ ← card-header ├──────────────────────────────────────────────────────────────┤ │ [operations / primary content…] │ │ │ │ Activities Commits Builds Files │ ← tabs (not sticky yet) │ ───────────────────────────────────────── │ │ Tab content… │ │ … │ └──────────────────────────────────────────────────────────────┘2. Today after scroll (problem)
Tabs stick; header (and its more-info) scroll away. Side info is unreachable without scrolling back up.
┌──────────────────────────────────────────────────────────────┐ │ Activities Commits Builds Files │ ← sticky tabs │ ───────────────────────────────────────── │ │ Tab content… │ │ … │ │ … more scrolled content … │ │ (no [···] here) │ └──────────────────────────────────────────────────────────────┘3. Proposed sticky / docked —
align-items-centerWhen the header trigger leaves the scrollport,
.sticky-tabs-rowgets.is-dockedand the docked more-info appears on the right of the sticky row. Withalign-items-center, the control is vertically centered with the tab labels.┌──────────────────────────────────────────────────────────────┐ │ Activities Commits Builds Files [···] │ ← sticky row │ ───────────────────────────────────────── │ dock sits mid-row │ Tab content… │ │ … │ └──────────────────────────────────────────────────────────────┘ ↑ tabs grow left ↑ dock (centered)4. Side info open
Existing rule
body.side-info-visible a.side-info { display: none }hides both the header and docked triggers. Pane takes the right side.┌────────────────────────────────────────────┬─────────────────┐ │ Activities Commits Builds Files │ Side info │ │ ───────────────────────────────────── │ ───────── │ │ Tab content… │ fields / │ │ … │ workspaces / │ │ │ … │ │ (no [···]) │ [×] │ └────────────────────────────────────────────┴─────────────────┘5. Transition summary
unscrolled scroll past header side info open ─────────── ────────────────── ────────────── header [···] shown header [···] off-screen all a.side-info hidden dock hidden dock shown in sticky row pane visibleSticky state uses the centered dock in (3) with
align-items-centeron.sticky-tabs-row.
| Type |
Improvement
|
| Priority |
Normal
|
| Assignee | |
| Labels |
No labels
|
Relates to #2968
Problem Statement
Currently:
.tabs): Located inside.card-body > .main.more-info): Located inside.card-headerWhen scrolling down:
.tabsusesposition: stickyand sticks totop: 0..more-infoscrolls out of view because its parent container (.card-header) leaves the viewport.Requirement
.tabsreachestop: 0and becomes sticky,.more-infoshould dynamically dock attop: 0alongside.tabs(sitting on the right side) so both are visible side-by-side without overlapping.Target Elements
Element A (Tabs Bar):
Element B (More Info Button):
Motivation
The
.more-infobutton, when the side info panel is hidden, currently scrolls out of view when the user scrolls down the page. This means that in order to access the.side-infopane, the user needs to scroll all the way to the top. However, as we have done in a past issue, we moved the Workspaces UI element from the top into the.side-infopane in order to not need to scroll all the way up to the top in the first place.Therefore, what we want to do is be able to expose the
.side-infopanel without needing to scroll all the way up to the top. This makes it easier for users to open and close the side info panel using the.more-infobutton no matter where they have scrolled in the page.Analysis
Current structure on issue detail (same pattern on build / PR detail):
Sticky on
.tabsworks because it lives inside the scrolling.main/.autofitchain. Sticky on.more-infocannot work while it stays under.card-header: once the header scrolls off, sticky is clipped by that ancestor. Existing CSS already hides triggers when the pane is open (.side-info-visible a.side-info { display: none }), and PR summary links already proxy-click the header trigger (pull-request-detail.js).Tabbablealready has a right-aligned.optionsslot (margin-left: auto), but it is owned by the selected tab’srenderOptions()— not a good place for a page-level more-info control without API changes.1. Technical strategy (recommended)
Recommended: sticky tabs row wrapper + second
SideInfoLink+IntersectionObserverSideInfoLink(recommended)SideInfoLink(Tippy / Ajax /SideInfoOpenedstay intact); layout reserved via flex on the sticky row; noposition:fixedmathulto a thin wrapper)position:fixedoverlay toggled by observer<a>into tabsWhy A: Default state keeps Element B in
.card-headerand Element A as the tab list. Only when the header trigger leaves the scrollport do we show a second trigger that already lives inside the sticky row, so it docks attop: 0beside the tabs with no fixed-position bookkeeping.2. Step-by-step implementation
Step 1 — Markup (e.g.
IssueDetailPage.html)Wrap tabs + docked trigger; move sticky to the wrapper so both stick together. Keep the original header link unchanged:
nav-tabs-stickyfrom theul(sticky moves to the row)..more-info-dockis hidden (see CSS), so the unscrolled layout matches today.Mirror on
BuildDetailPage/PullRequestDetailPage(same header + sticky tabs pattern).Step 2 — Java
Add a second
SideInfoLink("moreInfoDock")next to the existingSideInfoLink("moreInfo"). Both broadcastSideInfoOpened; no click proxying required (unlike PR summary text links).Step 3 — CSS (
base.cssor page CSS)Optionally move the existing
.nav-tabs-line.nav-tabs-stickyrules onto.sticky-tabs-rowso all sticky-tab pages share one definition.Step 4 — JS (
IntersectionObserver)Observe the header trigger against the real scroll root (the nearest scrolling ancestor, typically the
.autofitscroller — notviewportalone):Call from page
onDomReady(and after Ajax refreshes that replace the header/tabs).Stuck detection: “header more-info not intersecting” ≈ “tabs have reached sticky” for this layout, because the header sits above the tabs. If pixel-perfect stick detection is needed, observe a 1px sentinel placed immediately above
.sticky-tabs-rowinstead.Step 5 — Collision / alignment
display: flex; tabsflex-grow-1; dockflex-shrink-0+ml-3— same spacing as the header control.flex-wrapon theulif needed); dock stays on the right of the row.padding-righthack required because the dock participates in flex layout only while.is-dockedis on (when hidden viadisplay: noneit takes no space).Step 6 — Transitions & edge cases
SideInfoLink— same as header.side-info-visible a.side-info { display: none }hides bothposition: staticexception on the row (same as current sticky tabs).more-info-dockif desired; avoid animating layout width of the tab list if it feels jumpySideInfoOpened3. Proposed code touch points (diff outline)
Implementation would touch roughly:
IssueDetailPage.html(+ Build/PR detail HTML) — sticky row +moreInfoDockIssueDetailPage.java(+ Build/PR) —new SideInfoLink("moreInfoDock")base.css—.sticky-tabs-row/.is-docked(lift styles off.nav-tabs-sticky)side-info.js— shareddockMoreInfoWithStickyTabsissue-detail.js/pull-request-detail.js/ build detail JS — call helper fromonDomReady