aboutsummaryrefslogtreecommitdiffstats
path: root/core/src/components/AppMenuEntry.vue
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/components/AppMenuEntry.vue')
-rw-r--r--core/src/components/AppMenuEntry.vue52
1 files changed, 34 insertions, 18 deletions
diff --git a/core/src/components/AppMenuEntry.vue b/core/src/components/AppMenuEntry.vue
index cef6d413dcd..1bf160f0695 100644
--- a/core/src/components/AppMenuEntry.vue
+++ b/core/src/components/AppMenuEntry.vue
@@ -4,9 +4,11 @@
-->
<template>
- <li class="app-menu-entry"
+ <li ref="containerElement"
+ class="app-menu-entry"
:class="{
'app-menu-entry--active': app.active,
+ 'app-menu-entry--truncated': needsSpace,
}">
<a class="app-menu-entry__link"
:href="app.href"
@@ -15,7 +17,7 @@
:target="app.target ? '_blank' : undefined"
:rel="app.target ? 'noopener noreferrer' : undefined">
<AppMenuIcon class="app-menu-entry__icon" :app="app" />
- <span class="app-menu-entry__label">
+ <span ref="labelElement" class="app-menu-entry__label">
{{ app.name }}
</span>
</a>
@@ -24,11 +26,26 @@
<script setup lang="ts">
import type { INavigationEntry } from '../types/navigation'
+import { onMounted, ref, watch } from 'vue'
import AppMenuIcon from './AppMenuIcon.vue'
-defineProps<{
+const props = defineProps<{
app: INavigationEntry
}>()
+
+const containerElement = ref<HTMLLIElement>()
+const labelElement = ref<HTMLSpanElement>()
+const needsSpace = ref(false)
+
+/** Update the space requirements of the app label */
+function calculateSize() {
+ const maxWidth = containerElement.value!.clientWidth
+ // Also keep the 0.5px letter spacing in mind
+ needsSpace.value = (maxWidth - props.app.name.length * 0.5) < (labelElement.value!.scrollWidth)
+}
+// Update size on mounted and when the app name changes
+onMounted(calculateSize)
+watch(() => props.app.name, calculateSize)
</script>
<style scoped lang="scss">
@@ -37,8 +54,6 @@ defineProps<{
width: var(--header-height);
height: var(--header-height);
position: relative;
- // Needed to prevent jumping when hover an entry (keep in sync with :hover styles)
- transition: width var(--animation-quick) ease-in-out;
&__link {
position: relative;
@@ -65,9 +80,8 @@ defineProps<{
left: 50%;
top: 50%;
display: block;
- min-width: 100%;
transform: translateX(-50%);
- width: 100%;
+ max-width: 100%;
text-overflow: ellipsis;
overflow: hidden;
letter-spacing: -0.5px;
@@ -115,25 +129,27 @@ defineProps<{
// Adjust the width when an entry is focussed
// The focussed / hovered entry should grow, while both neighbors need to shrink
- &:hover,
- &:focus-within {
- width: calc(var(--header-height) + var(--app-menu-entry-growth));
+ &--truncated:hover,
+ &--truncated:focus-within {
+ .app-menu-entry__label {
+ max-width: calc(var(--header-height) + var(--app-menu-entry-growth));
+ }
// The next entry needs to shrink half the growth
+ .app-menu-entry {
- width: calc(var(--header-height) - (var(--app-menu-entry-growth) / 2));
- .app-menu-entry__icon {
- margin-inline-end: calc(var(--app-menu-entry-growth) / 2);
+ .app-menu-entry__label {
+ font-weight: normal;
+ max-width: calc(var(--header-height) - var(--app-menu-entry-growth));
}
}
}
// The previous entry needs to shrink half the growth
- &:has(+ .app-menu-entry:hover),
- &:has(+ .app-menu-entry:focus-within) {
- width: calc(var(--header-height) - (var(--app-menu-entry-growth) / 2));
- .app-menu-entry__icon {
- margin-inline-start: calc(var(--app-menu-entry-growth) / 2);
+ &:has(+ .app-menu-entry--truncated:hover),
+ &:has(+ .app-menu-entry--truncated:focus-within) {
+ .app-menu-entry__label {
+ font-weight: normal;
+ max-width: calc(var(--header-height) - var(--app-menu-entry-growth));
}
}
}