Unread Visual Guide - nself-org/nchat GitHub Wiki

Unread System - Visual Guide

Visual reference for all unread indicator components and their usage contexts.


Component Gallery

1. UnreadBadge - Channel List

Usage: Show unread count on channel items in sidebar

<UnreadBadge unreadCount={5} mentionCount={2} size="sm" position="inline" />

Visual States:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ # general              [5]     β”‚  ← Regular unread (blue/gray badge)
β”‚ # random               [3]     β”‚
β”‚ # design               ●       β”‚  ← Mention (red dot, no count)
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ # announcements        [2]     β”‚  ← Mention with count (red badge)
β”‚ # support              ●       β”‚  ← Unread dot (gray)
β”‚ # feedback                     β”‚  ← No unread
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Color Coding:

  • πŸ”΄ Red = Has mentions (@user, @everyone, @here)
  • πŸ”΅ Blue/Gray = Has unread (no mentions)
  • βšͺ None = No unread

Sizes:

  • sm: 16px height (default for sidebar)
  • md: 20px height (for headers)
  • lg: 24px height (for emphasis)

2. UnreadDot - Minimal Indicator

Usage: Subtle indicator when count isn't needed

<UnreadDot unreadCount={3} mentionCount={1} size="sm" />

Visual States:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ # general          ●           β”‚  ← Red dot (mentions)
β”‚ # random           ●           β”‚  ← Blue dot (unread)
β”‚ # design                       β”‚  ← No dot (all read)
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Best For:

  • Muted channels (show indicator but not count)
  • Compact views
  • Mobile interfaces
  • Overflow menus

3. UnreadLine - Message List Divider

Usage: Visual separator showing where unread messages start

<UnreadLine count={10} label="New Messages" />

Visual Appearance:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                           β”‚
β”‚ [Alice] Hey everyone!                     β”‚
β”‚ [Bob] What's up?                          β”‚
β”‚                                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ πŸ”” 10 New Messages ────────────  ← Unread line
β”‚                                           β”‚
β”‚ [Charlie] Just joined                     β”‚
β”‚ [Dave] Welcome!                           β”‚
β”‚                                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Styling:

  • Red horizontal line
  • Centered label with background
  • Bell icon
  • Count + custom text

Animation:

  • Fades in from above
  • Subtle slide down

4. SidebarUnread - Full Channel Item

Usage: Complete channel list item with integrated unread badge

<SidebarUnread
  channelName="general"
  channelType="channel"
  unreadCount={5}
  mentionCount={2}
  isMuted={false}
  isActive={false}
  onClick={() => {}}
/>

Visual States:

Active Channel:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ ┃ # general           [5]      β”‚  ← Blue accent bar
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Unread Channel:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   # random            [3]      β”‚  ← Bold text
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Mention:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   # design            [2]      β”‚  ← Red badge, bold
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Muted:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   # support           ●        β”‚  ← Dimmed, dot only
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Read:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   # feedback                   β”‚  ← Normal text, no badge
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

States:

  • Active: Highlighted background + accent bar
  • Unread: Bold text + badge
  • Mention: Bold text + red badge
  • Muted: Reduced opacity + tooltip
  • Read: Normal appearance

5. JumpToUnread - Navigation Button

Usage: Floating button to jump to first unread message

<JumpToUnreadButton
  hasUnread={true}
  unreadCount={5}
  mentionCount={2}
  onJumpToUnread={handleJump}
  variant="default"
/>

Visual Variants:

Default (Full featured):

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                 β”‚
β”‚         Message List            β”‚
β”‚                                 β”‚
β”‚         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚         β”‚ πŸ”” 2 mentionsβ”‚         β”‚  ← Floating button
β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”‚                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Compact (Icon only):

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                 β”‚
β”‚         Message List            β”‚
β”‚                                 β”‚
β”‚             β”Œβ”€β”€β”€β”               β”‚
β”‚             β”‚ ⬇ β”‚               β”‚  ← Compact button
β”‚             β””β”€β”€β”€β”˜               β”‚
β”‚                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Minimal (Subtle):

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                 β”‚
β”‚         Message List            β”‚
β”‚                                 β”‚
β”‚      ⬇ Jump to 5 unread         β”‚  ← Minimal text
β”‚                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Colors:

  • πŸ”΄ Red background = Has mentions
  • πŸ”΅ Blue background = Has unread (no mentions)
  • βšͺ Default background = Jump to latest

Position Options:

  • bottom-center (default)
  • bottom-right
  • bottom-left

6. MentionHighlight - Message Background

Usage: Highlight messages that mention current user

<MentionHighlight isMentioned={true}>
  <MessageItem message={message} />
</MentionHighlight>

Visual Effect:

Normal Message:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ [Alice] Hey team!                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Mentioned Message:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
┃ [Alice] Hey @you, check this!     β”‚  ← Red left border
┃ (background: red-500/10)          β”‚  ← Subtle red tint
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Styling:

  • Left border: 4px solid red
  • Background: bg-red-500/10 (light) / bg-red-500/20 (dark)
  • Full message width

Layout Examples

Full Chat Interface

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  SIDEBAR         β”‚  MAIN CHAT                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                  β”‚  Header                          β”‚
β”‚ CHANNELS         β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚                  β”‚  β”‚ # general                  β”‚  β”‚
β”‚ # general   [5]  β”‚  β”‚ ⬆⬇ 3 unread channels      β”‚  β”‚
β”‚ # random    [3]  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚ # design    [2]  β”‚                                  β”‚
β”‚ # support   ●    β”‚  MESSAGES                        β”‚
β”‚ # feedback       β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚                  β”‚  β”‚ [Alice] Hey!               β”‚  β”‚
β”‚ DMs              β”‚  β”‚ [Bob] What's up?           β”‚  β”‚
β”‚                  β”‚  β”‚                            β”‚  β”‚
β”‚ Alice       [2]  β”‚  β”œβ”€β”€β”€β”€ πŸ”” 5 New Messages ─────  β”‚
β”‚ Bob         ●    β”‚  β”‚                            β”‚  β”‚
β”‚ Charlie          β”‚  ┃ [Dave] Hey @you!          β”‚  β”‚ ← Mention
β”‚                  β”‚  β”‚ [Eve] Anyone there?        β”‚  β”‚
β”‚                  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                  β”‚                                  β”‚
β”‚                  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚
β”‚                  β”‚  β”‚ πŸ”” 2 mentions    β”‚            β”‚ ← Jump button
β”‚                  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚
β”‚                  β”‚                                  β”‚
β”‚                  β”‚  Message Input                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Mobile View

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  ☰  # general       [5]  β”‚  ← Header with badge
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                          β”‚
β”‚  Messages                β”‚
β”‚                          β”‚
β”‚  ──── πŸ”” 5 New ────      β”‚  ← Unread line
β”‚                          β”‚
β”‚  [Alice] Hey!            β”‚
β”‚                          β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚
β”‚  β”‚ ⬇ 5 unread   β”‚        β”‚  ← Compact jump button
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚
β”‚                          β”‚
β”‚  [Input]                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

State Transitions

Channel Badge Lifecycle

1. No unread
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ # generalβ”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

2. First unread arrives
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ # general [1]β”‚  ← Badge appears (animated)
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

3. More unreads accumulate
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ # general [5]β”‚  ← Count increases
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

4. Mention arrives
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ # general [2]β”‚  ← Turns red
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

5. Channel opened, scrolled
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ # generalβ”‚    ← Badge fades out
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Jump Button Lifecycle

1. At bottom, no unread
   [Hidden]

2. New message arrives
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ ⬇ 1 new      β”‚  ← Appears (slide up)
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

3. More messages
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ ⬇ 5 new      β”‚  ← Count updates
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

4. Mention received
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ πŸ”” 2 mentionsβ”‚  ← Turns red
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

5. Button clicked
   [Scrolls to unread]
   [Hidden after scroll]

Color Palette

Light Mode

/* Regular unread */
--unread-bg: rgba(59, 130, 246, 0.1) /* blue-500/10 */ --unread-badge: rgba(59, 130, 246, 1)
  /* blue-500 */ --unread-text: rgba(59, 130, 246, 1) /* blue-500 */ /* Mentions */
  --mention-bg: rgba(239, 68, 68, 0.1) /* red-500/10 */ --mention-badge: rgba(239, 68, 68, 1)
  /* red-500 */ --mention-text: rgba(255, 255, 255, 1) /* white */
  --mention-border: rgba(239, 68, 68, 1) /* red-500 */;

Dark Mode

/* Regular unread */
--unread-bg: rgba(59, 130, 246, 0.2) /* blue-500/20 */ --unread-badge: rgba(59, 130, 246, 1)
  /* blue-500 */ --unread-text: rgba(96, 165, 250, 1) /* blue-400 */ /* Mentions */
  --mention-bg: rgba(239, 68, 68, 0.2) /* red-500/20 */ --mention-badge: rgba(239, 68, 68, 1)
  /* red-500 */ --mention-text: rgba(255, 255, 255, 1) /* white */
  --mention-border: rgba(239, 68, 68, 1) /* red-500 */;

Animations

Badge Entrance

// Framer Motion
<motion.div initial={{ scale: 0 }} animate={{ scale: 1 }} exit={{ scale: 0 }}>
  <Badge />
</motion.div>

Effect: Pop in from center

Jump Button Entrance

<motion.div
  initial={{ opacity: 0, y: 20, scale: 0.9 }}
  animate={{ opacity: 1, y: 0, scale: 1 }}
  exit={{ opacity: 0, y: 20, scale: 0.9 }}
  transition={{ type: 'spring', stiffness: 300, damping: 25 }}
>
  <Button />
</motion.div>

Effect: Slide up with spring bounce

Unread Line Entrance

<motion.div initial={{ opacity: 0, y: -10 }} animate={{ opacity: 1, y: 0 }}>
  <UnreadLine />
</motion.div>

Effect: Slide down fade in


Responsive Behavior

Desktop (>1024px)

  • Full badges with counts
  • Default jump button variant
  • Sidebar always visible
  • Hover states active

Tablet (768px - 1024px)

  • Compact badges
  • Compact jump button
  • Collapsible sidebar
  • Touch-friendly targets

Mobile (<768px)

  • Dot indicators (no counts in tight spaces)
  • Minimal jump button
  • Swipe gestures
  • Larger touch targets (min 44px)

Accessibility

Screen Reader Labels

// Badge
<Badge aria-label="5 unread messages" />
<Badge aria-label="2 mentions" />

// Jump Button
<Button
  aria-label="Jump to 5 unread messages"
  aria-keyshortcuts="Alt+Shift+U"
/>

// Unread Line
<div
  role="separator"
  aria-label="Unread messages below"
/>

Keyboard Navigation

Tab          β†’ Focus next unread channel
Shift+Tab    β†’ Focus previous unread channel
Enter/Space  β†’ Activate focused item
Alt+Shift+U  β†’ Jump to unread
Alt+Shift+↑  β†’ Previous unread channel
Alt+Shift+↓  β†’ Next unread channel
Esc          β†’ Mark channel as read

Focus Indicators

All interactive elements have visible focus rings:

.focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

Performance Notes

Optimization Strategies

  1. Memoization

    • Use useMemo for count calculations
    • Use useCallback for handlers
    • Prevent unnecessary re-renders
  2. Virtual Lists

    • Unread indicators work with virtualized lists
    • Only render visible items
    • Maintain scroll position
  3. Debouncing

    • Mark as read debounced (1s default)
    • Storage saves debounced (100ms)
    • Scroll event throttled
  4. Lazy Loading

    • Load unread counts on demand
    • Progressive enhancement
    • Skeleton states for loading

Testing Visual Regressions

Storybook Stories

Create stories for each variant:

export const UnreadBadgeStory = {
  args: {
    unreadCount: 5,
    mentionCount: 0,
    size: 'sm',
  },
}

export const MentionBadgeStory = {
  args: {
    unreadCount: 5,
    mentionCount: 2,
    size: 'sm',
  },
}

Visual Testing Tools

  • Percy (visual regression)
  • Chromatic (Storybook)
  • Playwright (E2E screenshots)

Design Tokens

export const unreadTokens = {
  badge: {
    size: {
      sm: '16px',
      md: '20px',
      lg: '24px',
    },
    fontSize: {
      sm: '10px',
      md: '12px',
      lg: '14px',
    },
    padding: {
      sm: '2px 4px',
      md: '2px 6px',
      lg: '4px 8px',
    },
  },
  colors: {
    unread: 'blue-500',
    mention: 'red-500',
    muted: 'gray-400',
  },
  animation: {
    duration: '200ms',
    easing: 'ease-out',
  },
}

This visual guide provides a comprehensive reference for implementing and using unread indicators throughout nself-chat. Refer to component documentation for detailed API information.

⚠️ **GitHub.com Fallback** ⚠️