|
57 | 57 | <img |
58 | 58 | class="app-menu__current-app-icon" |
59 | 59 | :class="{ 'app-menu__current-app-icon--settings': currentApp.type === 'settings' }" |
60 | | - :src="currentApp.icon" |
| 60 | + :src="displayIcon" |
61 | 61 | alt="" |
62 | 62 | aria-hidden="true"> |
63 | 63 | </template> |
64 | 64 | <span class="app-menu__current-app-name"> |
65 | | - {{ currentApp.name }} |
| 65 | + {{ displayName }} |
66 | 66 | </span> |
67 | 67 | </NcButton> |
68 | 68 | </nav> |
@@ -160,11 +160,34 @@ export default defineComponent({ |
160 | 160 | ?? Object.values(this.settingsList).find((entry) => entry.active && !SETTINGS_ACTION_IDS.has(entry.id)) |
161 | 161 | }, |
162 | 162 |
|
163 | | - // aria-label overrides the inner span text, so the section name |
| 163 | + // Trigger label. Settings sub-section names ("Personal info", |
| 164 | + // "Appearance and accessibility", ...) are too long and varied to |
| 165 | + // surface in the header; collapse them all to a single "Settings". |
| 166 | + displayName(): string { |
| 167 | + if (!this.currentApp) { |
| 168 | + return '' |
| 169 | + } |
| 170 | + return this.currentApp.type === 'settings' |
| 171 | + ? t('core', 'Settings') |
| 172 | + : this.currentApp.name |
| 173 | + }, |
| 174 | +
|
| 175 | + // Match the collapsed label: a generic cog for any settings |
| 176 | + // sub-section instead of the per-section icon. |
| 177 | + displayIcon(): string { |
| 178 | + if (!this.currentApp) { |
| 179 | + return '' |
| 180 | + } |
| 181 | + return this.currentApp.type === 'settings' |
| 182 | + ? imagePath('core', 'actions/settings.svg') |
| 183 | + : this.currentApp.icon |
| 184 | + }, |
| 185 | +
|
| 186 | + // aria-label overrides the inner span text, so the displayed name |
164 | 187 | // has to be duplicated here for screen readers. |
165 | 188 | currentAppLabel(): string { |
166 | 189 | return this.currentApp |
167 | | - ? t('core', 'Open apps menu, currently in {app}', { app: this.currentApp.name }) |
| 190 | + ? t('core', 'Open apps menu, currently in {app}', { app: this.displayName }) |
168 | 191 | : t('core', 'Open apps menu') |
169 | 192 | }, |
170 | 193 |
|
@@ -452,23 +475,18 @@ export default defineComponent({ |
452 | 475 | } |
453 | 476 |
|
454 | 477 | &__current-app-name { |
455 | | - // Hidden by default so the icon-only trigger fits alongside the |
456 | | - // centered search input. The button's aria-label still announces the |
457 | | - // section name. At wide viewports we restore the label with a |
458 | | - // truncation cap as a safety net for long localized names. |
459 | | - display: none; |
460 | | -
|
461 | | - @media only screen and (min-width: 1400px) { |
462 | | - display: inline-block; |
463 | | - vertical-align: middle; |
464 | | - font-size: var(--default-font-size); |
465 | | - font-weight: 500; |
466 | | - white-space: nowrap; |
467 | | - letter-spacing: -0.5px; |
468 | | - overflow: hidden; |
469 | | - text-overflow: ellipsis; |
470 | | - max-width: clamp(160px, 18vw, 360px); |
471 | | - } |
| 478 | + // inline-block: inline elements ignore max-width + overflow. |
| 479 | + display: inline-block; |
| 480 | + vertical-align: middle; |
| 481 | + font-size: var(--default-font-size); |
| 482 | + font-weight: 500; |
| 483 | + white-space: nowrap; |
| 484 | + letter-spacing: -0.5px; |
| 485 | + overflow: hidden; |
| 486 | + text-overflow: ellipsis; |
| 487 | + // Cap width so long localized labels ellipsize instead of pushing |
| 488 | + // the header icons off-screen (.header-start doesn't shrink). |
| 489 | + max-width: clamp(80px, 22vw, 320px); |
472 | 490 | } |
473 | 491 |
|
474 | 492 | &__popover { |
|
0 commit comments