JSFiddle - React, Tailwind, and code Playground
author(s):
Tao Xin
HTML
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/vanjs-org/van/public/van-1.6.1.nomodule.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/[email protected]/dist/van-x.nomodule.min.js"></script>
CSS
body {
font-family: Arial, sans-serif;
}
.container {
display: flex;
height: 100vh;
}
.friend-list {
width: 180px;
background-color: #f3f3f3;
overflow-y: auto;
}
.friend-list ul {
list-style: none;
padding: 0;
margin: 0;
}
.friend-list ul li {
padding: 10px;
border-bottom: 1px solid #ccc;
position: relative;
padding-left: 30px;
}
.status-indicator {
height: 10px;
width: 10px;
border-radius: 50%;
display: inline-block;
position: absolute;
left: 10px;
top: 15px;
margin-right: 10px;
}
.online {
background-color: #008000;
}
.offline {
background-color: #808080;
}
.chat-messages {
width: 80%;
background-color: #fff;
overflow-y: auto;
}
.message {
padding: 15px;
border-bottom: 1px solid #eee;
}
JavaScript
const {div, li, span, ul} = van.tags
const serverState = {
friends: [
{name: "Aria Smith", online: true},
{name: "Evelyn Parker", online: true},
{name: "Liam Johnson", online: true},
{name: "Mateo Brown", online: true},
{name: "Ethan Wilson", online: false},
{name: "Jackson Garcia", online: false},
{name: "Lucas Anderson", online: false},
{name: "Mia Thomas", online: false},
{name: "Nora Martinez", online: false},
{name: "Zoe Davis", online: false},
],
messages: [],
}
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
async function* serverStateUpdates() {
yield serverState
while (true) {
await sleep(2000)
const friend = serverState.friends[Math.floor(Math.random() * serverState.friends.length)]
friend.online = !friend.online
serverState.friends.sort((a, b) => a.online !== b.online ?
(a.online ? -1 : 1) :
a.name.localeCompare(b.name))
serverState.messages.push(`${friend.name} has gone ${friend.online ? "online" : "offline"}`)
if (serverState.messages.length > 5) serverState.messages.shift()
yield serverState
}
}
const ChatApp = () => {
const appState = vanX.reactive({friends: [], messages: []})
;(async () => {for await (const state of serverStateUpdates()) vanX.replace(appState, state)})()
return div({class: "container"},
div({class: "friend-list"},
vanX.list(ul, appState.friends, ({val: v}) => li(
span({class: () => ["status-indicator", v.online ? "online" : "offline"].join(" ")}), " ",
() => v.name,
)),
),
vanX.list(div({class: "chat-messages"}), appState.messages, s => div({class: "message"}, s)),
)
}
van.add(document.body, ChatApp())