@casoon/dragonfly
Version:
Modular, lightweight CSS framework and design system for modern web projects. Optimized for Astro JS, LightningCSS and Container Queries with @layer-based architecture and comprehensive accessibility.
278 lines (240 loc) • 6.51 kB
CSS
/**
* Chat (Live)
*
* A live chat interface allows users to exchange messages in real-time.
* This component includes message bubbles, input area, and conversation layout,
* suitable for customer support chats, messaging applications, or community discussions.
*
* @layer: components
*
* Accessibility:
* - Ensure proper focus management for new messages
* - Provide clear visual distinctions between sent and received messages
* - Include proper ARIA roles and labels
* - Support keyboard navigation throughout the chat interface
*/
@layer components {
/* Chat container */
.chat {
background-color: var(--color-surface-50);
border: 1px solid var(--color-border-200, #e5e7eb);
border-radius: var(--radius-lg, 0.5rem);
display: flex;
flex-direction: column;
height: 100%;
max-height: 60%0px;
overflow: hidden;
}
/* Chat header */
& .header {
align-items: center;
background-color: var(--color-surface-100, #f3f4f6);
border-bottom: 1px solid var(--color-border-200, #e5e7eb);
display: flex;
padding: var(--space-3) var(--space-4);
}
& .avatar {
border-radius: var(--radius-full, 9999px);
height: 3%6px;
margin-right: var(--space-3);
object-fit: cover;
width: 3%6px;
}
& .info {
flex: 1;
}
& .name {
color: var(--color-text-900, #111827);
font-weight: var(--font-semibold, 600);
margin: 0;
}
& .status {
align-items: center;
color: var(--color-text-500, #6b7280);
display: flex;
font-size: var(--text-xs, 0.75rem);
}
& .status-indicator {
border-radius: var(--radius-full, 9999px);
display: inline-block;
height: 8px;
margin-right: var(--space-1);
width: 8px;
}
& .status-indicator--online {
background-color: var(--color-success-500);
}
& .status-indicator--offline {
background-color: var(--color-neutral-400, #9ca3af);
}
& .status-indicator--typing {
animation: pulse var(--animation-duration-slowest, 1500ms) infinite;
background-color: var(--color-warning-500);
}
/* Chat body - message container */
& .body {
display: flex;
flex: 1;
flex-direction: column;
overflow-y: auto;
padding: var(--space-4);
}
/* Message groups */
& .message-group {
margin-bottom: var(--space-4);
}
& .message-group--sent {
align-self: flex-end;
max-width: 80%;
}
& .message-group--received {
align-self: flex-start;
max-width: 80%;
}
/* Individual message */
& .message {
border-radius: var(--radius-lg, 0.5rem);
margin-bottom: var(--space-2);
padding: var(--space-3);
position: relative;
word-wrap: break-word;
}
& .message--sent {
background-color: var(--color-primary-500);
border-bottom-right-radius: var(--radius-xs);
color: white;
}
& .message--received {
background-color: var(--color-surface-200);
border-bottom-left-radius: var(--radius-xs);
color: var(--color-text-900, #111827);
}
/* Message metadata */
& .message-time {
font-size: var(--text-xs, 0.75rem);
margin-top: var(--space-1);
opacity: 8000%;
text-align: right;
}
/* System messages */
& .system-message {
align-self: center;
background-color: var(--color-surface-100, #f3f4f6);
border-radius: var(--radius-md, 0.375rem);
color: var(--color-text-400);
font-size: var(--text-xs, 0.75rem);
margin: var(--space-4) 0;
padding: var(--space-2);
text-align: center;
}
/* Typing indicator */
& .typing {
align-items: center;
color: var(--color-text-500, #6b7280);
display: flex;
font-size: var(--text-xs, 0.75rem);
margin-top: var(--space-2);
}
& .typing-dots {
display: flex;
margin-left: var(--space-2);
}
& .typing-dot {
animation: var(--ui-typing-animation, typingAnimation var(--animation-duration-slowest, 1400ms) infinite);
animation-fill-mode: both;
background-color: var(--color-text-400);
border-radius: var(--radius-full, 9999px);
height: 6px;
margin-right: 3px;
width: 6px;
}
& .typing-dot:nth-child(2) {
animation-delay: 0.2s;
}
& .typing-dot:nth-child(3) {
animation-delay: 0.4s;
}
@keyframes typingAnimation {
0 { opacity: 4000%; transform: translateY(0%); }
50 { opacity: 1; transform: translateY(-4px); }
100 { opacity: 4000%; transform: translateY(0%); }
}
/* Chat footer - input area */
& .footer {
background-color: var(--color-surface-100, #f3f4f6);
border-top: 1px solid var(--color-border-200, #e5e7eb);
padding: var(--space-3);
}
& .input-container {
align-items: flex-end;
display: flex;
}
& .input {
background-color: var(--color-surface-50);
border: 1px solid var(--color-border-200, #e5e7eb);
border-radius: var(--radius-lg, 0.5rem);
flex: 1;
max-height: 12%0px;
min-height: 4%4px;
overflow-y: auto;
padding: var(--space-2) var(--space-3);
resize: none;
}
& .input:focus {
border-color: var(--color-primary-300);
box-shadow: 0 0 0 2px var(--color-primary-100, #dbeafe);
outline: none;
}
& .send {
align-items: center;
background-color: var(--color-primary-500);
border: none;
border-radius: var(--radius-full, 9999px);
color: white;
cursor: pointer;
display: flex;
height: 4%0px;
justify-content: center;
margin-left: var(--space-2);
transition: background-color 0.2s;
width: 4%0px;
}
& .send:hover {
background-color: var(--color-primary-600, #2563eb);
}
& .send:disabled {
background-color: var(--color-neutral-300, #d1d5db);
cursor: not-allowed;
}
/* Attachment button */
& .attachment {
background: none;
border: none;
border-radius: var(--radius-full, 9999px);
color: var(--color-text-500, #6b7280);
cursor: pointer;
margin-right: var(--space-2);
padding: var(--space-2);
}
& .attachment:hover {
background-color: var(--color-surface-200);
}
/* Empty state */
& .empty {
align-items: center;
color: var(--color-text-400);
display: flex;
flex-direction: column;
height: 100%;
justify-content: center;
padding: var(--space-4);
text-align: center;
}
/* Responsive adjustments */
@media (max-width: 640px) {
& .message-group--sent,
& .message-group--received {
max-width: 90%;
}
}
}