webdevpuneet.com

Team Presence List — Online Status Roster HTML CSS JS

Team Presence List · Cards · Plain HTML, CSS & JS · Live preview

CategoryCards

Copy & paste

Source Code

<div class="tpl-card">
  <div class="tpl-head">
    <h3>Team</h3>
    <input type="text" id="tplSearch" placeholder="Search teammates…">
  </div>
  <div class="tpl-list" id="tplList"></div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Four-state status system
Online, away, do-not-disturb, and offline each get a distinct, hover-labeled status dot.
Automatic status-priority sorting
The most reachable teammates always surface first, computed via a simple status-to-rank lookup rather than alphabetical order.
Combined name/role search
One input filters across two fields at once, re-applying the same status sort to whatever matches.
Initials-based colored avatars
No avatar images required — names are converted to two-letter initials on a per-person accent color.
Accessible status tooltips
Every dot's title attribute spells out its meaning explicitly, not relying on color alone.
Descriptive status sub-line
Each row shows role plus a human status note ("Away · back at 2pm"), not just a bare status word.
Graceful no-results state
An empty search result shows a clear message naming the unmatched query instead of a blank list.
Scrollable, fixed-height list
A capped max-height with internal scrolling keeps the card a consistent size regardless of roster length.

About this UI Snippet

Team Presence List — Status Dots, Status-Sorted Order & Live Search Filter

Screenshot of the Team Presence List snippet rendered live

A presence list — the roster of teammates with a small colored dot showing who's around right now — is the ambient-awareness feature that makes a tool feel alive: a glance tells you who you can ping immediately versus who's away or offline. This snippet builds the full pattern: four status states, automatic status-priority sorting, and a live filter over name and role.

Four statuses, one rank-based sort

Each person has a status of online, away, dnd (do not disturb), or offline, each rendered as its own dot color. Rather than sorting alphabetically (which buries available teammates among offline ones), STATUS_RANK maps each status to a sort priority — online first, away and dnd tied in the middle, offline last — so the people you're most likely to want to reach right now surface at the top of the list automatically, every time the list re-renders.

Search filters without losing the status sort

Typing in the search box filters PEOPLE by a case-insensitive match against *either* the name or the role, then re-applies the same status-priority sort to the filtered results — so searching "engineering" still shows online engineers before offline ones, rather than returning matches in their original array order. This is implemented as one small render(filter) function that does both jobs every time, so there's no separate "now reapply the sort" step to forget.

Initials avatars from a name string

initials() splits a person's name on spaces, takes the first character of each of the first two words, and uppercases them — turning "Priya Nair" into "PN" with no avatar image required. Each person also has an assigned background color, so even a long roster of initials-only avatars stays visually distinguishable at a glance, the same approach used by Slack and Linear when a user hasn't set a profile photo.

A status dot that explains itself on hover

Every status dot carries a title attribute with its full label ("Do not disturb," not just a red color), so hovering any dot — even without reading the subtext line beside the name — gives an explicit, accessible explanation of what that color means, rather than asking users to memorize a color-coding convention.

Presence as a trust signal, not just decoration

A status dot's real job is answering "will this person actually see my message soon?" before you send it — which is why ordering by reachability matters more than it might first seem. A roster sorted alphabetically with status as an afterthought makes every lookup a manual scan; sorting by status first turns the same data into an answer at a glance, the difference between a nice-to-have indicator and a genuinely useful piece of team-coordination UI.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA team roster renders with seven people, each with a colored avatar, a status dot, and a status-aware sub-line.
  2. 2
    Read the orderingOnline teammates appear first, then away/do-not-disturb, then offline — not alphabetical order.
  3. 3
    Search by name or roleType in the search box to filter the list by either field; the status-priority sort still applies to the filtered results.
  4. 4
    Hover a status dotA native tooltip shows the full status label (e.g. "Do not disturb") even without reading the row's subtext.
  5. 5
    Clear the searchEmpty the search field to see the full roster again, still sorted by status.
  6. 6
    Connect real presence dataReplace the static PEOPLE array's status field with live values from your presence service (WebSocket or polling), calling render() with the current search value on every update.

Real-world uses

Common Use Cases

Team chat and collaboration apps
Build the Slack or Teams style who is around roster, with online, away, do-not-disturb and offline each given a distinct dot.
Customer support dashboards
Show which agents are free to take a conversation, with the most reachable people automatically sorted to the top.
Project management assignment
Pair with a kanban board so assignees can be chosen by availability, using a search that filters name and role together.
Company directories
Provide a searchable company staff directory, with initials-based coloured avatars so that no profile images are required for the list.
Meetings and compact summaries
Show participant availability in video apps, and condense the roster into an avatar group where space is limited.

Got questions?

Frequently Asked Questions

Open a WebSocket (or poll a presence API) and, on each status update, find the matching person in PEOPLE by id and update their status field, then call render(currentSearchValue) to re-sort and re-render the list with the new live status.

Store a lastActiveAt timestamp per person instead of (or alongside) the note string, and compute a relative label ("3h ago", "yesterday") at render time using a small time-formatting helper, refreshing it periodically with setInterval so it stays accurate without a full data refetch.

Add an avatarUrl field to each person object, and in render(), conditionally output an <img> tag when it's present, falling back to the existing initials-and-color div when it's missing — so the component degrades gracefully for people without a profile photo.

Group PEOPLE into buckets by status using the same STATUS_RANK order, render a header (e.g. "Online — 3") above each non-empty bucket's rows, and skip headers for empty buckets — the underlying filter and per-person row template stay the same.

In React, keep people and the search query in useState and derive the sorted/filtered list with useMemo; in Vue, use a computed property over a reactive people array; in Angular, use a component method or pipe for the same filter-then-sort logic. The status-rank sorting is plain array logic that needs no changes across frameworks.