aboutsummaryrefslogtreecommitdiffstats
path: root/core/src
diff options
context:
space:
mode:
authorFerdinand Thiessen <opensource@fthiessen.de>2024-08-05 13:08:16 +0200
committerAndy Scherzinger <info@andy-scherzinger.de>2024-08-07 21:29:00 +0200
commit91f78936c94e2124d14defead1fa4ce14e7ee734 (patch)
tree60c09bbec93a38e50f9c1fa6b6ee07bac4119af5 /core/src
parent609fa7d5db69c7724ad42615e2146bef4f714c76 (diff)
downloadnextcloud-server-91f78936c94e2124d14defead1fa4ce14e7ee734.tar.gz
nextcloud-server-91f78936c94e2124d14defead1fa4ce14e7ee734.zip
fix: Ensure app overflow menu is rendered centered
1. Fix app menu overflow button to be centered 2. Ensure the overflow calculation always just removed one element (incl. refactor to use `@vueuse`) 3. Ensure we use 1.5 line height for app menu, otherwise some languages look squashed under the app icon Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
Diffstat (limited to 'core/src')
-rw-r--r--core/src/components/AppMenu.vue79
-rw-r--r--core/src/components/AppMenuEntry.vue10
2 files changed, 46 insertions, 43 deletions
diff --git a/core/src/components/AppMenu.vue b/core/src/components/AppMenu.vue
index 33e1a194f3c..f982776827e 100644
--- a/core/src/components/AppMenu.vue
+++ b/core/src/components/AppMenu.vue
@@ -4,7 +4,8 @@
-->
<template>
- <nav class="app-menu"
+ <nav ref="appMenu"
+ class="app-menu"
:aria-label="t('core', 'Applications menu')">
<ul class="app-menu__list">
<AppMenuEntry v-for="app in mainAppList"
@@ -29,7 +30,8 @@ import type { INavigationEntry } from '../types/navigation'
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
import { loadState } from '@nextcloud/initial-state'
import { n, t } from '@nextcloud/l10n'
-import { defineComponent } from 'vue'
+import { useElementSize } from '@vueuse/core'
+import { defineComponent, ref } from 'vue'
import AppMenuEntry from './AppMenuEntry.vue'
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
@@ -46,40 +48,47 @@ export default defineComponent({
},
setup() {
+ const appMenu = ref()
+ const { width: appMenuWidth } = useElementSize(appMenu)
return {
t,
n,
+ appMenu,
+ appMenuWidth,
}
},
data() {
const appList = loadState<INavigationEntry[]>('core', 'apps', [])
-
return {
appList,
- appLimit: 0,
- observer: null as ResizeObserver | null,
}
},
computed: {
+ appLimit() {
+ const maxApps = Math.floor(this.appMenuWidth / 50)
+ if (maxApps < this.appList.length) {
+ // Ensure there is space for the overflow menu
+ return Math.max(maxApps - 1, 0)
+ }
+ return maxApps
+ },
+
mainAppList() {
return this.appList.slice(0, this.appLimit)
},
+
popoverAppList() {
return this.appList.slice(this.appLimit)
},
},
mounted() {
- this.observer = new ResizeObserver(this.resize)
- this.observer.observe(this.$el)
- this.resize()
subscribe('nextcloud:app-menu.refresh', this.setApps)
},
beforeDestroy() {
- this.observer!.disconnect()
unsubscribe('nextcloud:app-menu.refresh', this.setApps)
},
@@ -96,54 +105,44 @@ export default defineComponent({
setApps({ apps }: { apps: INavigationEntry[]}) {
this.appList = apps
},
-
- resize() {
- const availableWidth = (this.$el as HTMLElement).offsetWidth
- let appCount = Math.floor(availableWidth / 50) - 1
- const popoverAppCount = this.appList.length - appCount
- if (popoverAppCount === 1) {
- appCount--
- }
- if (appCount < 1) {
- appCount = 0
- }
- this.appLimit = appCount
- },
},
})
</script>
<style scoped lang="scss">
.app-menu {
- width: 100%;
display: flex;
- flex-shrink: 1;
- flex-wrap: wrap;
+ flex: 1 1;
+ width: 0;
&__list {
display: flex;
flex-wrap: nowrap;
}
- // Adjust the overflow NcActions styles as they are directly rendered on the background
- &__overflow :deep(.button-vue--vue-tertiary) {
- opacity: .7;
- margin: 3px;
- filter: var(--background-image-invert-if-bright);
+ &__overflow {
+ margin-block: auto;
- /* Remove all background and align text color if not expanded */
- &:not([aria-expanded="true"]) {
- color: var(--color-background-plain-text);
+ // Adjust the overflow NcActions styles as they are directly rendered on the background
+ :deep(.button-vue--vue-tertiary) {
+ opacity: .7;
+ margin: 3px;
+ filter: var(--background-image-invert-if-bright);
- &:hover {
- opacity: 1;
- background-color: transparent !important;
+ /* Remove all background and align text color if not expanded */
+ &:not([aria-expanded="true"]) {
+ color: var(--color-background-plain-text);
+
+ &:hover {
+ opacity: 1;
+ background-color: transparent !important;
+ }
}
- }
- &:focus-visible {
- opacity: 1;
- outline: none !important;
+ &:focus-visible {
+ opacity: 1;
+ outline: none !important;
+ }
}
}
diff --git a/core/src/components/AppMenuEntry.vue b/core/src/components/AppMenuEntry.vue
index aada0c63930..ead86759e4a 100644
--- a/core/src/components/AppMenuEntry.vue
+++ b/core/src/components/AppMenuEntry.vue
@@ -33,6 +33,7 @@ defineProps<{
<style scoped lang="scss">
.app-menu-entry {
+ --app-menu-entry-font-size: 12px;
width: var(--header-height);
height: var(--header-height);
position: relative;
@@ -54,8 +55,7 @@ defineProps<{
&__label {
opacity: 0;
position: absolute;
- font-size: 12px;
- line-height: 1.25;
+ font-size: var(--app-menu-entry-font-size);
// this is shown directly on the background
color: var(--color-background-plain-text);
text-align: center;
@@ -71,6 +71,10 @@ defineProps<{
letter-spacing: -0.5px;
}
+ &__icon {
+ font-size: var(--app-menu-entry-font-size);
+ }
+
&--active {
// When hover or focus, show the label and make it bolder than the other entries
.app-menu-entry__label {
@@ -117,7 +121,7 @@ defineProps<{
.app-menu__list:focus-within {
// Move icon up so that the name does not overflow the icon
.app-menu-entry__icon {
- margin-block-end: calc(1.5 * 12px); // font size of label * line height
+ margin-block-end: 1lh;
}
// Make the label visible