Replace progress bar with animated typing indicator

Replaced the chat progress bar in Ask.razor with a modern animated "typing indicator" using three bouncing dots. Updated Ask.razor.css to remove old progress bar styles and add new keyframes and accessibility improvements for the typing dots. This enhances user experience by clearly signaling when the assistant is responding.
This commit is contained in:
Marco Minerva
2026-07-28 15:18:33 +02:00
parent a225d61b3f
commit 3390d94c81
2 changed files with 43 additions and 28 deletions
@@ -46,10 +46,10 @@
@if (message.Text is null) @if (message.Text is null)
{ {
<div class="card card-text d-inline-block p-3 px-3 m-1"> <div class="card card-text d-inline-block p-3 px-3 m-1">
<div class="progress-chat" role="progressbar" aria-label="I'm thinking" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"> <div class="typing-indicator" role="status" aria-label="The assistant is typing">
<div class="progress-bar-chat"> <span class="typing-dot"></span>
<div class="progress-bar-indeterminate"></div> <span class="typing-dot"></span>
</div> <span class="typing-dot"></span>
</div> </div>
</div> </div>
} }
@@ -43,40 +43,55 @@ input[type="checkbox"] + label {
border-radius: 8px; border-radius: 8px;
} }
.progress-chat { .typing-indicator {
width: 200px; display: flex;
height: 6px; align-items: center;
gap: 5px;
height: 8px;
} }
.progress-bar-chat { .typing-dot {
height: 6px; width: 8px;
background-color: rgba(5, 114, 206, 0.15); height: 8px;
width: 100%; border-radius: 50%;
overflow: hidden; background-color: rgb(5, 114, 206);
border-radius: 999px; animation: typing-bounce 1.2s infinite ease-in-out both;
} }
.progress-bar-indeterminate { .typing-dot:nth-child(1) {
width: 40%; animation-delay: -0.24s;
height: 100%;
border-radius: 999px;
background: linear-gradient(90deg, rgba(5, 114, 206, 0) 0%, rgb(5, 114, 206) 50%, rgba(5, 114, 206, 0) 100%);
animation: indeterminate-animation 1.4s infinite cubic-bezier(0.65, 0, 0.35, 1);
} }
@keyframes indeterminate-animation { .typing-dot:nth-child(2) {
0% { animation-delay: -0.12s;
transform: translateX(-100%);
} }
100% { @keyframes typing-bounce {
transform: translateX(350%); 0%, 80%, 100% {
transform: translateY(0);
opacity: .4;
}
40% {
transform: translateY(-5px);
opacity: 1;
} }
} }
@media (prefers-reduced-motion: reduce) { @media (prefers-reduced-motion: reduce) {
.progress-bar-indeterminate { .typing-dot {
animation-duration: 3s; animation-name: typing-fade;
animation-duration: 2s;
}
@keyframes typing-fade {
0%, 80%, 100% {
opacity: .4;
}
40% {
opacity: 1;
}
} }
} }