|
12 | 12 | <header> |
13 | 13 |
|
14 | 14 | <KToolbar |
| 15 | + ref="toolbar" |
15 | 16 | type="clear" |
16 | 17 | :style="{ |
17 | 18 | overflowX: 'auto', |
|
21 | 22 | :raised="false" |
22 | 23 | > |
23 | 24 | <template #icon> |
24 | | - <!-- Menu button for logged in users --> |
25 | 25 | <KIconButton |
26 | 26 | v-if="loggedIn" |
27 | 27 | icon="menu" |
28 | 28 | :color="$themeTokens.text" |
29 | 29 | :ariaLabel="$tr('openMenu')" |
30 | 30 | @click="toggleSidePanel" |
31 | 31 | /> |
32 | | - |
33 | | - <!-- Logo link for non-logged in users --> |
34 | 32 | <KExternalLink |
35 | 33 | v-else |
36 | 34 | :href="homeLink" |
|
45 | 43 |
|
46 | 44 | <template #brand> |
47 | 45 | <div |
48 | | - class="text-truncate" |
| 46 | + class="studio-navigation__title-container" |
49 | 47 | style="max-width: 160px" |
50 | 48 | > |
51 | | - <span class="studio-navigation__title"> |
52 | | - {{ title || $tr('title') }} |
| 49 | + <span> |
| 50 | + {{ truncatedTitle }} |
53 | 51 | </span> |
54 | 52 | </div> |
55 | 53 | </template> |
|
120 | 118 | </KToolbar> |
121 | 119 |
|
122 | 120 | </header> |
123 | | - |
124 | | - |
125 | | - |
126 | | - <!-- Tabs extension area (for when tabs are provided) --> |
127 | 121 | <div |
128 | 122 | v-if="hasTabs" |
129 | 123 | :aria-label="$tr('mainNavigationLabel')" |
|
164 | 158 | </div> |
165 | 159 | </div> |
166 | 160 | </div> |
167 | | - |
168 | | - <!-- Side panel (replaces MainNavigationDrawer) --> |
169 | 161 | <SidePanelModal |
170 | 162 | v-if="loggedIn && sidePanelOpen" |
171 | 163 | alignment="left" |
|
284 | 276 | </div> |
285 | 277 | </template> |
286 | 278 | </SidePanelModal> |
287 | | - |
288 | | - <!-- Language Switcher Modal --> |
289 | 279 | <LanguageSwitcherModal |
290 | 280 | v-if="showLanguageModal" |
291 | 281 | :style="{ color: $themeTokens.text }" |
|
326 | 316 | isOverflowing: false, |
327 | 317 | canScrollLeft: false, |
328 | 318 | canScrollRight: false, |
| 319 | + toolbarWidth: 0, |
329 | 320 | }; |
330 | 321 | }, |
331 | 322 | computed: { |
|
354 | 345 | copyrightLink() { |
355 | 346 | return 'https://learningequality.org/'; |
356 | 347 | }, |
| 348 | + truncatedTitle() { |
| 349 | + const displayTitle = this.title || this.$tr('title'); |
| 350 | + const offset = (this.$refs.studioNavigationActions?.clientWidth || 0) + 100; |
| 351 | + const averageCharWidth = 10; |
| 352 | + const availableWidth = this.toolbarWidth - offset; |
| 353 | + const maxChars = availableWidth > 0 ? Math.floor(availableWidth / averageCharWidth) : 1; |
| 354 | + return this.truncateText(displayTitle, maxChars); |
| 355 | + }, |
357 | 356 | userMenuItems() { |
358 | 357 | const items = []; |
359 | 358 |
|
|
408 | 407 | mounted() { |
409 | 408 | this.updateTabIndices(); |
410 | 409 | this.updateWindowWidth(); |
411 | | - window.addEventListener('resize', this.updateWindowWidth); |
| 410 | + this.updateToolbarWidth(); |
| 411 | + window.addEventListener('resize', this.handleResize); |
412 | 412 | const el = this.$refs.tabsContainer; |
413 | 413 | if (el) { |
414 | 414 | el.addEventListener('scroll', this.checkScrollPositions); |
|
421 | 421 | updated() { |
422 | 422 | this.$nextTick(() => { |
423 | 423 | this.updateTabIndices(); |
| 424 | + this.updateToolbarWidth(); |
424 | 425 | }); |
425 | 426 | }, |
426 | 427 | beforeDestroy() { |
427 | | - window.removeEventListener('resize', this.updateWindowWidth); |
| 428 | + window.removeEventListener('resize', this.handleResize); |
428 | 429 | }, |
429 | 430 | methods: { |
430 | 431 | ...mapActions(['logout']), |
|
510 | 511 | this.sidePanelOpen = false; |
511 | 512 | this.showLanguageModal = true; |
512 | 513 | }, |
| 514 | + handleResize() { |
| 515 | + this.updateWindowWidth(); |
| 516 | + this.updateToolbarWidth(); |
| 517 | + }, |
513 | 518 | updateWindowWidth() { |
514 | 519 | this.windowWidth = window.innerWidth; |
515 | 520 | }, |
| 521 | + updateToolbarWidth() { |
| 522 | + this.toolbarWidth = this.$refs.studioNavigation?.clientWidth || 0; |
| 523 | + }, |
| 524 | + truncateText(value, maxLength) { |
| 525 | + if (value && value.length > maxLength) { |
| 526 | + return value.substring(0, maxLength) + '...'; |
| 527 | + } |
| 528 | + return value; |
| 529 | + }, |
516 | 530 | handleTabsKeydown(event) { |
517 | 531 | const tabs = this.getTabElements(); |
518 | 532 | if (!tabs.length) return; |
|
633 | 647 | } |
634 | 648 | } |
635 | 649 |
|
636 | | - .studio-navigation__title { |
637 | | - display: block; |
638 | | - width: 100%; |
| 650 | + .studio-navigation__title-container { |
| 651 | + display: block; |
| 652 | + overflow: hidden; |
| 653 | + white-space: nowrap; |
| 654 | + text-overflow: ellipsis; |
639 | 655 | font-size: 20px; |
640 | 656 | font-weight: 500; |
641 | 657 | padding-inline-start: 20px; |
|
649 | 665 |
|
650 | 666 | .studio-navigation__actions { |
651 | 667 | display: flex; |
652 | | - gap: 16px; |
653 | 668 | align-items: center; |
654 | 669 | } |
655 | 670 |
|
|
0 commit comments