Skip to content
Open
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
@@ -0,0 +1,105 @@
<template>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blocking: The acceptance criteria in issue #5631 state:

If there is no unit test suite, a new one is created. Do not use obsolete @vue/test-utils approach. Instead, use @testing-library/vue.

This new component has no unit tests. Consider adding tests for:

  • Rendering with required header prop
  • Rendering with optional text prop
  • Default slot content
  • Named back slot override

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the input, I will work on this 👍


<div class="message-layout-wrapper">
<StudioPage
:centered="true"
:marginTop="0"
>
<div class="message-layout-content">
<h1 class="message-header">
{{ header }}
</h1>
<p
v-if="text"
class="message-text"
>
{{ text }}
</p>
<div class="message-slot-container">
<slot></slot>
</div>
<div class="link-container">
<slot name="back">
<KRouterLink
:to="{ name: 'Main' }"
:text="$tr('backToLogin')"
:appearance="basic - link"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blocking: Invalid attribute syntax - :appearance="basic - link" will evaluate as JavaScript (undefined - undefined = NaN), not as a string.

Should be:

appearance="basic-link"

(No colon, plain string attribute)

Copy link
Contributor Author

@AadarshM07 AadarshM07 Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @rtibbles, I understood what you mentioned. I was facing an issue where binding the value as a string causes the link to appear covered with the link color. I tried removing the appearance prop since basic-link is the default, but the issue still there. Interestingly, when I bind it using JavaScript (sorry my mistake it was undefined here) the problem does not occur.

This has been confusing, as the issue only appears when using StudioMessageLayout . I will continue working on this to find the fix. I would also appreciate your insights on this

The issue:
image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting - I'm not seeing anything in the styles for your new component that would cause this - if you inspect the link itself, and look at the CSS inspector, are you able to see where this background colour is coming from?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @rtibbles , After spending some time debugging this is the conclusion that I came to regarding the issue.

Why this happens:
At its core, KRouterLink seems to be built on top of the button system (mixins: [buttonMixin]). Even when we use appearance="basic-link", it still creates a button that looks like a link. Further investigation in buttonMixin.js:64–71 made it clear that this is what applies the blue color on hover and the styling around the link text. And as it is a button it wraps up the rectangular space.

Why this issue was not experienced before:
Previously, most usages of KRouterLink were inside Vuetify layouts such as VApp, VLayout, and VFlex. Vuetify adds its own global CSS rules to components. Essentially, vuetify's styles were overriding the button styles applied by KRouterLink. Inorder to valide my point over here , I did an experiment with KRouterLink:

  • When the component is rendered in a normal blank page, the button-like styling is visible.
image
  • When the same component is wrapped inside Vuetify, it appears as a normal link.

I may be missing something. If you also think this is an issue, I do have an approach in mind that i'd like to share.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you look at the KRouterLink documentation page, you can see that when it is rendered as a basic-link, it does not have this styling: https://design-system.learningequality.org/krouterlink something is going awry if this is the case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you look at the KRouterLink documentation page, you can see that when it is rendered as a basic-link, it does not have this styling: https://design-system.learningequality.org/krouterlink something is going awry if this is the case.

Oh yes, my earlier conclusion about it being primarily caused by buttonMixin may not be the exact root issue if that is the case.

I now suspect the issue is on the Studio side, as @MisRob also mentioned that this can happen in some cases. One fix I found that seems like a win-win and does not affect behavior is to add background-color: transparent !important; to the link styling in button.scss (KDS side fix). This resolves the link styling issue here and is unlikely to impact other KRouterLink use cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting - I'm not seeing anything in the styles for your new component that would cause this - if you inspect the link itself, and look at the CSS inspector, are you able to see where this background colour is coming from?

@rtibbles like you suggested, while inspecting the CSS I noticed that Vue Router automatically adds classes such as router-link-active for active links, which might be picking up styles and adding this blue background. In earlier cases, since most usages of KRouterLink were within Vuetify layouts, its global styles may have been neutralizing these effects, which could explain why it wasn't seen before.

image

Copy link
Member

@MisRob MisRob Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into it more @AadarshM07. It sounds that the KDS adjustments you found out supports hypothesis that it may be a Vuetify style that's causing the problem, but we don't yet know how exactly what's happening on Studio side right? With my suggestion I meant if you could track the root cause in Studio (and post reference to related styles). Then the decision on how to proceed will be clearer (adjusting KDS is possible in some cases, but doing so prematurely would lead to adding style that, after Vuetify is removed, wouldn't be needed).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And the screenshot is good information - it's just not clear to me where those styles are coming from exactly in the codebase - and that's what I'm trying to get at.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MisRob , Thanks for the input, I understood the mission. Also, I have an event over the next two days, so I may be a bit slow to respond, but I will look into this and update you right after

/>
</slot>
</div>
</div>
</StudioPage>
</div>

</template>


<script>
import StudioPage from '../../shared/views/StudioPage';
export default {
name: 'StudioMessageLayout',
components: {
StudioPage,
},
props: {
header: {
type: String,
required: true,
},
text: {
type: String,
required: false,
default: '',
},
},
$trs: {
backToLogin: 'Continue to sign-in page',
},
};
</script>


<style scoped>
.message-layout-wrapper {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.message-layout-content {
display: flex;
flex-direction: column;
max-width: 900px;
padding-top: 80px;
padding-bottom: 48px;
text-align: center;
}
.message-header {
margin-bottom: 6px;
font-size: 24px;
font-weight: bold;
}
.message-text {
margin-top: 4px;
margin-bottom: 20px;
font-size: 16px;
}
.message-slot-container {
max-width: 400px;
margin: 24px auto 0;
text-align: center;
}
.link-container {
margin-top: 24px;
}
</style>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>

<MessageLayout :header="$tr('accountDeletedTitle')">
<StudioMessageLayout :header="$tr('accountDeletedTitle')">
<template #back>
<KRouterLink
:to="{ name: 'Main' }"
Expand All @@ -9,19 +9,19 @@
appearance="raised-button"
/>
</template>
</MessageLayout>
</StudioMessageLayout>

</template>


<script>
import MessageLayout from '../../components/MessageLayout';
import StudioMessageLayout from '../../components/MessageLayout';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blocking: Wrong import path - this still imports from MessageLayout (the old Vuetify component) instead of StudioMessageLayout.

Should be:

import StudioMessageLayout from '../../components/StudioMessageLayout';

This defeats the purpose of this PR for AccountDeleted.vue - it's still using Vuetify.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry about that, my mistake

export default {
name: 'AccountDeleted',
components: {
MessageLayout,
StudioMessageLayout,
},
$trs: {
accountDeletedTitle: 'Account successfully deleted',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>

<MessageLayout :header="$tr('accountCreatedTitle')">
<StudioMessageLayout :header="$tr('accountCreatedTitle')">
<template #back>
<KRouterLink
:to="{ name: 'Main' }"
Expand All @@ -9,19 +9,19 @@
appearance="raised-button"
/>
</template>
</MessageLayout>
</StudioMessageLayout>

</template>


<script>

import MessageLayout from '../../components/MessageLayout';
import StudioMessageLayout from '../../components/StudioMessageLayout';

export default {
name: 'AccountCreated',
components: {
MessageLayout,
StudioMessageLayout,
},
$trs: {
accountCreatedTitle: 'Account successfully created',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>

<MessageLayout
<StudioMessageLayout
:header="$tr('title')"
:text="$tr('text')"
>
Expand All @@ -10,19 +10,19 @@
:to="{ name: 'RequestNewActivationLink' }"
appearance="raised-button"
/>
</MessageLayout>
</StudioMessageLayout>

</template>


<script>

import MessageLayout from '../../components/MessageLayout';
import StudioMessageLayout from '../../components/StudioMessageLayout';

export default {
name: 'AccountNotActivated',
components: {
MessageLayout,
StudioMessageLayout,
},
$trs: {
title: 'Account has not been activated',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>

<MessageLayout
<StudioMessageLayout
:header="$tr('activationExpiredTitle')"
:text="$tr('activationExpiredText')"
>
Expand All @@ -10,19 +10,19 @@
:to="{ name: 'RequestNewActivationLink' }"
appearance="raised-button"
/>
</MessageLayout>
</StudioMessageLayout>

</template>


<script>

import MessageLayout from '../../components/MessageLayout';
import StudioMessageLayout from '../../components/StudioMessageLayout';

export default {
name: 'ActivationExpired',
components: {
MessageLayout,
StudioMessageLayout,
},
$trs: {
activationExpiredTitle: 'Activation failed',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>

<MessageLayout
<StudioMessageLayout
:header="$tr('activationReSentTitle')"
:text="$tr('activationReSentText')"
/>
Expand All @@ -10,12 +10,12 @@

<script>

import MessageLayout from '../../components/MessageLayout';
import StudioMessageLayout from '../../components/StudioMessageLayout';

export default {
name: 'ActivationLinkReSent',
components: {
MessageLayout,
StudioMessageLayout,
},
$trs: {
activationReSentTitle: 'Instructions sent. Thank you!',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>

<MessageLayout
<StudioMessageLayout
:header="$tr('header')"
:text="$tr('text')"
/>
Expand All @@ -10,12 +10,12 @@

<script>

import MessageLayout from '../../components/MessageLayout';
import StudioMessageLayout from '../../components/StudioMessageLayout';

export default {
name: 'ActivationSent',
components: {
MessageLayout,
StudioMessageLayout,
},
$trs: {
header: 'Activation link sent',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>

<MessageLayout
<StudioMessageLayout
:header="$tr('passwordInstructionsHeader')"
:text="$tr('passwordInstructionsText')"
/>
Expand All @@ -10,12 +10,12 @@

<script>

import MessageLayout from '../../components/MessageLayout';
import StudioMessageLayout from '../../components/StudioMessageLayout';

export default {
name: 'PasswordInstructionsSent',
components: {
MessageLayout,
StudioMessageLayout,
},
$trs: {
passwordInstructionsHeader: 'Instructions sent. Thank you!',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>

<MessageLayout
<StudioMessageLayout
:header="$tr('resetExpiredTitle')"
:text="$tr('resetExpiredText')"
>
Expand All @@ -10,19 +10,19 @@
:to="{ name: 'ForgotPassword' }"
appearance="raised-button"
/>
</MessageLayout>
</StudioMessageLayout>

</template>


<script>

import MessageLayout from '../../components/MessageLayout';
import StudioMessageLayout from '../../components/StudioMessageLayout';

export default {
name: 'ResetLinkExpired',
components: {
MessageLayout,
StudioMessageLayout,
},
$trs: {
resetExpiredTitle: 'Reset link expired',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>

<MessageLayout
<StudioMessageLayout
:header="$tr('header')"
:text="$tr('text')"
/>
Expand All @@ -10,12 +10,12 @@

<script>

import MessageLayout from '../../components/MessageLayout';
import StudioMessageLayout from '../../components/StudioMessageLayout';

export default {
name: 'ResetPasswordSuccess',
components: {
MessageLayout,
StudioMessageLayout,
},
$trs: {
header: 'Password reset successfully',
Expand Down