mirror of
https://github.com/go-gitea/gitea.git
synced 2026-09-08 22:13:26 +09:00
fix(ui): avoid layout shifts in overflow-menu and repo filter (#37818)
Eliminate two layout shifts in the menu, one related to non-existant label on page load and one to `0` value rendering. Signed-off-by: silverwind <me@silverwind.io> Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com> Co-authored-by: bircni <bircni@icloud.com>
This commit is contained in:
co-authored by
Claude
bircni
parent
b4eb8c03c4
commit
14ca2e7526
@@ -522,6 +522,11 @@ overflow-menu {
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* hide until JS has arranged the items, so the un-collapsed menu is never painted */
|
||||||
|
overflow-menu:not([data-ready]) {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
overflow-menu .overflow-menu-popup {
|
overflow-menu .overflow-menu-popup {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: calc(100% + 8px);
|
top: calc(100% + 8px);
|
||||||
@@ -609,6 +614,12 @@ overflow-menu .overflow-menu-button:hover {
|
|||||||
|
|
||||||
overflow-menu .ui.label {
|
overflow-menu .ui.label {
|
||||||
margin-left: 7px !important; /* save some space */
|
margin-left: 7px !important; /* save some space */
|
||||||
|
font-variant-numeric: tabular-nums; /* equal-width digits so counts don't reflow the row */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* count not loaded yet, keep the reserved space so filling it in does not shift the row */
|
||||||
|
overflow-menu .ui.label:empty {
|
||||||
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.activity-bar-graph {
|
.activity-bar-graph {
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ export default defineComponent({
|
|||||||
finalPage: 1,
|
finalPage: 1,
|
||||||
searchQuery,
|
searchQuery,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
|
initialSearchDone: false,
|
||||||
staticPrefix: assetUrlPrefix,
|
staticPrefix: assetUrlPrefix,
|
||||||
counts: {} as Record<string, number>,
|
counts: {} as Record<string, number>,
|
||||||
repoTypes: {
|
repoTypes: {
|
||||||
@@ -186,7 +187,6 @@ export default defineComponent({
|
|||||||
this.reposFilter = filter;
|
this.reposFilter = filter;
|
||||||
this.repos = [];
|
this.repos = [];
|
||||||
this.page = 1;
|
this.page = 1;
|
||||||
this.counts[`${filter}:${this.archivedFilter}:${this.privateFilter}`] = 0;
|
|
||||||
this.searchRepos();
|
this.searchRepos();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -247,7 +247,6 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
this.page = 1;
|
this.page = 1;
|
||||||
this.repos = [];
|
this.repos = [];
|
||||||
this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = 0;
|
|
||||||
this.searchRepos();
|
this.searchRepos();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -261,7 +260,6 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
this.page = 1;
|
this.page = 1;
|
||||||
this.repos = [];
|
this.repos = [];
|
||||||
this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = 0;
|
|
||||||
this.searchRepos();
|
this.searchRepos();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -276,7 +274,6 @@ export default defineComponent({
|
|||||||
this.page = 1;
|
this.page = 1;
|
||||||
}
|
}
|
||||||
this.repos = [];
|
this.repos = [];
|
||||||
this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = 0;
|
|
||||||
await this.searchRepos();
|
await this.searchRepos();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -308,6 +305,7 @@ export default defineComponent({
|
|||||||
} catch {
|
} catch {
|
||||||
if (searchedURL === this.searchURL) {
|
if (searchedURL === this.searchURL) {
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
|
this.initialSearchDone = true;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -329,6 +327,7 @@ export default defineComponent({
|
|||||||
this.finalPage = Math.ceil(count / this.searchLimit);
|
this.finalPage = Math.ceil(count / this.searchLimit);
|
||||||
this.updateHistory();
|
this.updateHistory();
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
|
this.initialSearchDone = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -449,7 +448,8 @@ export default defineComponent({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<overflow-menu class="ui secondary pointing tabular borderless menu repos-filter">
|
<!-- stay hidden until the first count arrives, otherwise the label resizes after paint -->
|
||||||
|
<overflow-menu class="ui secondary pointing tabular borderless menu repos-filter" :class="{'tw-invisible': !initialSearchDone}">
|
||||||
<div class="overflow-menu-items tw-justify-center">
|
<div class="overflow-menu-items tw-justify-center">
|
||||||
<a class="item" tabindex="0" :class="{active: reposFilter === 'all'}" @click="changeReposFilter('all')">
|
<a class="item" tabindex="0" :class="{active: reposFilter === 'all'}" @click="changeReposFilter('all')">
|
||||||
{{ textAll }}
|
{{ textAll }}
|
||||||
|
|||||||
@@ -213,6 +213,7 @@ window.customElements.define('overflow-menu', class extends HTMLElement {
|
|||||||
if (newWidth !== this.lastWidth) {
|
if (newWidth !== this.lastWidth) {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
this.updateItems();
|
this.updateItems();
|
||||||
|
this.setAttribute('data-ready', ''); // reveal via CSS [data-ready]
|
||||||
});
|
});
|
||||||
this.lastWidth = newWidth;
|
this.lastWidth = newWidth;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user