Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@
<nav>
<KToolbar
ref="toolbar"
:showIcon="true"
:style="toolbarStyle"
>
<template #icon>
<template #leading-actions>
<KIconButton
icon="close"
:color="getThemeToken('textColor')"
Expand Down
6 changes: 3 additions & 3 deletions kolibri/plugins/learn/frontend/views/LearningActivityBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
:progress="contentProgress"
class="progress-icon"
/>
<template #icon>
<template #leading-actions>
<KIconButton
icon="back"
data-testid="backButton"
Expand All @@ -43,7 +43,7 @@
/>
</template>

<template #actions>
<template #trailing-actions>
<Transition name="downloading-loader">
<!--
wrapping span needed here because
Expand Down Expand Up @@ -640,7 +640,7 @@
display: flex;
}

/deep/ .k-toolbar-nav-icon {
/deep/ .k-toolbar-leading-actions {
min-width: 0; // avoids early resource title truncation on Safari and Mac
margin-left: 0; // prevents icon cutoff
}
Expand Down
264 changes: 97 additions & 167 deletions packages/kolibri/components/pages/AppBarPage/internal/AppBar.vue
Original file line number Diff line number Diff line change
@@ -1,139 +1,112 @@
<template>

<div
<header
v-show="!$isPrint"
ref="appBar"
:style="{
backgroundColor: themeConfig.appBar.background,
color: themeConfig.appBar.textColor,
}"
>
<header>
<SkipNavigationLink />

<KToolbar
:removeNavIcon="showAppNavView"
type="clear"
class="app-bar"
:style="{
height: topBarHeight + 'px',
color: themeConfig.appBar.textColor,
}"
:raised="false"
:removeBrandDivider="true"
<SkipNavigationLink />

<KToolbar
class="app-bar"
:style="{
height: topBarHeight + 'px',
color: themeConfig.appBar.textColor,
backgroundColor: themeConfig.appBar.background,
}"
:title="title"
:raised="false"
>
<template
v-if="!showAppNavView"
#leading-actions
>
<KTextTruncator
:text="truncatedTitle"
:maxLines="1"
<KIconButton
icon="menu"
data-onboarding-id="menubar"
:color="themeConfig.appBar.textColor"
:ariaLabel="$tr('openNav')"
@click="$emit('toggleSideNav')"
/>
<template
v-if="!showAppNavView"
#icon
</template>

<template #brand>
<img
v-if="themeConfig.appBar.topLogo"
:src="themeConfig.appBar.topLogo.src"
:alt="themeConfig.appBar.topLogo.alt"
:style="themeConfig.appBar.topLogo.style"
:class="showAppNavView ? 'brand-logo-left' : 'brand-logo'"
>
<KIconButton
icon="menu"
data-onboarding-id="menubar"
:color="themeConfig.appBar.textColor"
:ariaLabel="$tr('openNav')"
@click="$emit('toggleSideNav')"
/>
</template>

<template #brand>
<img
v-if="themeConfig.appBar.topLogo"
:src="themeConfig.appBar.topLogo.src"
:alt="themeConfig.appBar.topLogo.alt"
:style="themeConfig.appBar.topLogo.style"
:class="showAppNavView ? 'brand-logo-left' : 'brand-logo'"
>
</template>

<template
v-if="showNavigation"
#navigation
</template>

<template #trailing-actions>
<div
ref="appBarActions"
aria-live="polite"
:style="{
paddingBottom: '6px',
}"
>
<slot name="sub-nav">
<Navbar
v-if="links.length > 0"
:style="hiddenNavbarStyle"
:navigationLinks="links"
:title="title"
@update-overflow-count="overflowCount = $event"
<slot name="app-bar-actions"></slot>
<span v-if="isLearner">
<KIcon
ref="pointsButton"
icon="pointsActive"
:ariaLabel="$tr('pointsAriaLabel')"
:color="$themeTokens.primary"
/>
</slot>
</template>

<template #actions>
<div
ref="appBarActions"
aria-live="polite"
:style="{
paddingBottom: '6px',
}"
>
<slot name="app-bar-actions"></slot>
<span v-if="isLearner">
<KIcon
ref="pointsButton"
icon="pointsActive"
:ariaLabel="$tr('pointsAriaLabel')"
:color="$themeTokens.primary"
/>
<div
v-if="!windowIsSmall"
class="points-description"
>
{{ $formatNumber(totalPoints) }}
</div>
<div
v-if="pointsDisplayed"
class="points-popover"
:style="{
color: $themeTokens.text,
padding: '8px',
backgroundColor: $themeTokens.surface,
}"
>
{{ $tr('pointsMessage', { points: totalPoints }) }}
</div>
</span>
<span
v-if="isUserLoggedIn"
tabindex="-1"
<div
v-if="!windowIsSmall"
class="points-description"
>
<KIcon
icon="person"
:style="{
fill: themeConfig.appBar.textColor,
height: '24px',
width: '24px',
margin: '4px',
top: '8px',
}"
/>
<span class="username">
{{ usernameForDisplay }}
</span>
{{ $formatNumber(totalPoints) }}
</div>
<div
v-if="pointsDisplayed"
class="points-popover"
:style="{
color: $themeTokens.text,
padding: '8px',
backgroundColor: $themeTokens.surface,
}"
>
{{ $tr('pointsMessage', { points: totalPoints }) }}
</div>
</span>
<span
v-if="isUserLoggedIn"
tabindex="-1"
>
<KIcon
icon="person"
:style="{
fill: themeConfig.appBar.textColor,
height: '24px',
width: '24px',
margin: '4px',
top: '8px',
}"
/>
<span class="username">
{{ usernameForDisplay }}
</span>
</div>
</template>
</KToolbar>
</header>
<div
v-show="showNavigation && !showAppNavView && !showTopNavBar"
class="subpage-nav"
>
<slot name="sub-nav">
<Navbar
v-if="links.length > 0"
:class="{ 'sub-nav': !showTopNavBar }"
:navigationLinks="links"
:title="title"
/>
</slot>
</div>
</div>
</span>
</div>
</template>

<template
v-if="showNavigation && !showAppNavView && (links.length > 0 || $scopedSlots['sub-nav'])"
#extension
>
<slot name="sub-nav">
<Navbar
:navigationLinks="links"
:title="title"
/>
</slot>
</template>
</KToolbar>
</header>

</template>

Expand Down Expand Up @@ -214,40 +187,13 @@
data() {
return {
pointsDisplayed: false,
appBarWidth: 0,
overflowCount: 0,
};
},
computed: {
// temp hack for the VF plugin
usernameForDisplay() {
return !hashedValuePattern.test(this.username) ? this.username : this.fullName;
},
showTopNavBar() {
return this.overflowCount === 0;
},
truncatedTitle() {
if (!this.title) return '';
// Dynamically truncate title based on remaining space in AppBar
const offset = this.$refs.appBarActions?.clientWidth + 100;
const averageCharWidth = 10;
const availableWidth = this.appBarWidth - offset;
const maxChars = availableWidth > 0 ? Math.floor(availableWidth / averageCharWidth) : 1;
return this.truncateText(this.title, maxChars);
},
hiddenNavbarStyle() {
if (this.showTopNavBar) {
return {};
}
// Hide top navbar, but keep it in the DOM for overflow calulations
const rightOffset = `${this.title.length * 10 + 250}px`;
return {
pointerEvents: 'none',
opacity: '0',
position: 'fixed',
right: rightOffset,
};
},
},
created() {
if (this.isLearner) {
Expand All @@ -257,13 +203,10 @@
beforeDestroy() {
window.removeEventListener('click', this.handleWindowClick);
window.removeEventListener('keydown', this.handlePopoverByKeyboard, true);
window.removeEventListener('resize', this.updateAppBarWidth);
},
mounted() {
window.addEventListener('click', this.handleWindowClick);
window.addEventListener('keydown', this.handlePopoverByKeyboard, true);
window.addEventListener('resize', this.updateAppBarWidth);
this.updateAppBarWidth();
},
methods: {
handleWindowClick(event) {
Expand All @@ -285,15 +228,6 @@
this.pointsDisplayed = false;
}
},
updateAppBarWidth() {
this.appBarWidth = this.$refs.appBar?.clientWidth || 0;
},
truncateText(value, maxLength) {
if (value && value.length > maxLength) {
return value.substring(0, maxLength) + '...';
}
return value;
},
},
$trs: {
openNav: {
Expand Down Expand Up @@ -421,8 +355,4 @@
font-size: 14px;
}

/deep/ .sub-nav .items {
margin-top: 0;
}

</style>
Loading