From 03a82a57d2fc825923735c4863febcffdc6dccfc Mon Sep 17 00:00:00 2001 From: whereareiam Date: Thu, 22 Oct 2026 18:46:26 +0200 Subject: [PATCH] feat(repo): GitHub's branch row and README box header on the Code page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Measured against github.com (signed in) from 1280 down to 400px: - Branches and Tags links: weight 500 with a 600 count, a 21px line and an invisible 1px border, so their icons sit where GitHub's do. - The Code button collapses to its icon and caret (49px) beside Add file, with a 16px caret. - The row narrows in GitHub's steps: Add file becomes a 34px "+" below 1280px, the branch and tag counts go below 1080px, Go to file becomes an 87px button below 1012px, and both move into the "…" menu below 544px instead of 768px. - README box header: underline tabs for the README (Forgejo's "README") and, at the repository root, its code of conduct, contributing guide, license and security policy, which open the file; an outline menu (the shared dropdown) lists the rendered README's headings by level. Below 544px the README box reaches the screen edges. Co-Authored-By: Claude Opus 5.5 --- public/assets/js/readme-outline.js | 29 +++++++++++ styles/components/repo/file_picker.ts | 3 +- styles/components/repo/repo_files.ts | 72 +++++++++++++++++++-------- styles/templates/repo/home.ts | 66 ++++++++++++++++++++++-- styles/templates/repo/view_content.ts | 13 +++++ templates/repo/readme/outline.tmpl | 2 + templates/repo/readme/tabs.tmpl | 20 ++++++++ templates/repo/view_content.tmpl | 6 ++- templates/repo/view_file.tmpl | 6 ++- 9 files changed, 187 insertions(+), 30 deletions(-) create mode 100644 public/assets/js/readme-outline.js create mode 100644 templates/repo/readme/outline.tmpl create mode 100644 templates/repo/readme/tabs.tmpl diff --git a/public/assets/js/readme-outline.js b/public/assets/js/readme-outline.js new file mode 100644 index 00000000..73d324dc --- /dev/null +++ b/public/assets/js/readme-outline.js @@ -0,0 +1,29 @@ +(() => { + // GitHub's README outline: the rendered headings, indented by level, built when the menu first opens. + const outline = document.querySelector("[data-readme-outline]"); + const menu = outline?.closest("details"); + const markup = document.querySelector("#readme .markup"); + if (!outline || !menu || !markup) return; + const headings = [...markup.querySelectorAll("h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]")]; + if (!headings.length) { + menu.hidden = true; + return; + } + menu.addEventListener( + "toggle", + () => { + for (const heading of headings) { + const link = document.createElement("a"); + link.className = "theme-dropdown-action"; + link.href = `#${heading.id.replace(/^user-content-/, "")}`; + link.dataset.level = heading.tagName.slice(1); + link.textContent = heading.textContent.trim(); + outline.before(link); + } + }, + { once: true } + ); + outline.addEventListener("click", event => { + if (event.target.closest("a")) menu.open = false; + }); +})(); diff --git a/styles/components/repo/file_picker.ts b/styles/components/repo/file_picker.ts index b5c7732e..38154b0c 100644 --- a/styles/components/repo/file_picker.ts +++ b/styles/components/repo/file_picker.ts @@ -107,7 +107,8 @@ export default css` overflow: hidden; clip-path: inset(50%); } - @media (max-width: 767.98px) { + /* GitHub keeps Go to file down to 544px; below that it moves into the "…" menu. */ + @media (max-width: 543.98px) { .repo-file-picker { display: none; } diff --git a/styles/components/repo/repo_files.ts b/styles/components/repo/repo_files.ts index af565229..d375634a 100644 --- a/styles/components/repo/repo_files.ts +++ b/styles/components/repo/repo_files.ts @@ -81,6 +81,13 @@ const repoFiles = css` } } } + /* Below 544px GitHub lets the README box reach the screen edges; the file list keeps its gutter. */ + @media (max-width: 543.98px) { + #readme { + margin-left: -16px; + margin-right: -16px; + } + } #readme { .file-header { background: ${themeVars.color.body}; @@ -90,30 +97,55 @@ const repoFiles = css` svg { color: ${themeVars.color.text.light.num1}; } + /* GitHub's README box header: underline tabs for the README and the community files. */ .file-header-left { - padding: 6px 8px !important; - line-height: 1.45; - /* 伪元素宽度等于按钮宽度而不是父元素宽度 */ - position: relative; - &:hover { - background: ${themeVars.github.control.transparent.bgColor.hover}; - border-radius: ${otherThemeVars.border.radius}; - } - &:after { - content: ""; - background: ${themeVars.github.underlineNav.borderColor.active}; + padding: 0 !important; + } + .repo-readme-tabs { + display: flex; + flex-wrap: wrap; + gap: 8px; + & > a { + display: inline-flex; + align-items: center; + gap: 8px; + position: relative; + height: 32px; + padding: 6px 8px; border-radius: ${otherThemeVars.border.radius}; - bottom: -8px; - left: 0; - height: 2px; - position: absolute; - width: 100%; - } - a.muted:hover { - color: inherit; - text-decoration-line: none; + color: ${themeVars.color.text.self}; + font-size: 14px; + font-weight: 400; + line-height: 21px; + &:hover { + background: ${themeVars.github.control.transparent.bgColor.hover}; + text-decoration-line: none; + } + &.active { + font-weight: 600; + &::after { + content: ""; + position: absolute; + left: 0; + bottom: -8px; + width: 100%; + height: 2px; + border-radius: ${otherThemeVars.border.radius}; + background: ${themeVars.github.underlineNav.borderColor.active}; + } + } } } + /* The README outline indents each heading level by 16px. */ + .theme-dropdown-action[data-level="2"] { + padding-left: 24px; + } + .theme-dropdown-action[data-level="3"] { + padding-left: 40px; + } + .theme-dropdown-action:is([data-level="4"], [data-level="5"], [data-level="6"]) { + padding-left: 56px; + } .file-header-right { .btn-octicon { display: inline-flex; diff --git a/styles/templates/repo/home.ts b/styles/templates/repo/home.ts index 218d925a..f8bc962f 100644 --- a/styles/templates/repo/home.ts +++ b/styles/templates/repo/home.ts @@ -210,11 +210,6 @@ const repositoryHome = css` .page-content.repository.file.list .repo-button-row > .repo-button-row-left > .js-branch-tag-selector { flex: 0 0 auto; } - .page-content.repository.file.list .repo-button-row .repository-summary, - .page-content.repository.file.list .repo-button-row .repo-find-file, - .page-content.repository.file.list .repo-button-row .repo-add-file { - display: none; - } .page-content.repository.file.list .repo-code-dropdown { position: static; } @@ -254,6 +249,67 @@ const repositoryHome = css` } } + /* + * GitHub's branch row narrows in steps: Add file becomes a "+" below 1280px, the branch and tag counts go below + * 1080px, Go to file becomes a plain button below 1012px, and both leave for the "…" menu below 544px. + */ + @media (max-width: 1279.98px) { + .page-content.repository.file.list .repo-button-row .repo-add-file { + width: 34px; + min-width: 0; + padding: 0 !important; + justify-content: center; + & > .repo-add-file-label, + & > .dropdown.icon { + display: none; + } + } + } + @media (min-width: 1280px) { + .page-content.repository.file.list .repo-button-row .repo-add-file > .repo-add-file-icon { + display: none; + } + } + @media (max-width: 1079.98px) { + .page-content.repository.file.list .repo-button-row .repository-summary { + display: none; + } + } + @media (max-width: 1011.98px) { + .page-content.repository.file.list .repo-button-row .repo-file-picker { + width: auto; + } + .page-content.repository.file.list .repo-button-row .repo-find-file { + width: 87px; + padding: 0 12px; + background: ${themeVars.color.button}; + cursor: pointer; + & > svg, + & > kbd { + display: none; + } + & > input { + padding: 0; + text-align: center; + cursor: pointer; + &::placeholder { + color: ${themeVars.color.text.self}; + font-weight: 500; + } + } + } + } + @media (max-width: 543.98px) { + .page-content.repository.file.list .repo-button-row .repo-add-file { + display: none; + } + } + @media (min-width: 544px) { + .page-content.repository.file.list .repo-mobile-actions { + display: none !important; + } + } + @media (min-width: 768px) and (max-width: 984.98px) { .page-content.repository.file.list .repo-button-row .repo-code-dropdown > .content { left: 0; diff --git a/styles/templates/repo/view_content.ts b/styles/templates/repo/view_content.ts index 0bd0f66a..8862850b 100644 --- a/styles/templates/repo/view_content.ts +++ b/styles/templates/repo/view_content.ts @@ -30,11 +30,15 @@ const repoButtonRow = css` display: inline-flex; align-items: center; gap: 4px; + /* GitHub: an invisible 1px border, 4px padding, a 500 label and a 600 count. */ + border: 1px solid transparent; border-radius: ${otherThemeVars.border.radius}; color: ${themeVars.color.text.light.num1}; padding: 4px; height: 32px; min-height: 32px; + font-weight: 500; + line-height: 21px; &:hover { background-color: ${themeVars.github.control.transparent.bgColor.hover}; box-shadow: inset 0 0 0 1px ${themeVars.github.control.transparent.borderColor.active}; @@ -100,6 +104,15 @@ const repoToolbarDetails = css` padding: 5px 12px !important; } + /* Beside "Add file", GitHub's Code button is just its icon and caret, 49px wide. */ + & .repo-button-row-right:has(.repo-add-file) .repo-code-dropdown > summary.ui.primary.button { + gap: 2px; + padding: 5px 6px 5px 7px !important; + & > span { + display: none; + } + } + & .repo-code-dropdown > summary.ui.primary.button:hover { background: ${themeVars.github.button.primary.bgColor.hover} !important; } diff --git a/templates/repo/readme/outline.tmpl b/templates/repo/readme/outline.tmpl new file mode 100644 index 00000000..e76828d0 --- /dev/null +++ b/templates/repo/readme/outline.tmpl @@ -0,0 +1,2 @@ +{{/* readme-outline.js puts the rendered README's headings here when the menu opens. */}} + diff --git a/templates/repo/readme/tabs.tmpl b/templates/repo/readme/tabs.tmpl new file mode 100644 index 00000000..0d44e658 --- /dev/null +++ b/templates/repo/readme/tabs.tmpl @@ -0,0 +1,20 @@ +{{- /* GitHub's README box header: README first, then the repository's community files in its order. Those files are +not rendered on this page, so their tabs open the file itself. */ -}} + diff --git a/templates/repo/view_content.tmpl b/templates/repo/view_content.tmpl index 58543349..aad9d0dd 100644 --- a/templates/repo/view_content.tmpl +++ b/templates/repo/view_content.tmpl @@ -47,7 +47,8 @@ {{if and .CanWriteCode .IsViewBranch (not .Repository.IsMirror) (not .Repository.IsArchived) (not .IsViewFile)}}