Chat — OutfitKit
Chat
Layout de mensajería con sidebar de conversaciones + hilo principal. Construido a partir de primitivos: no existe ningún componente Chat en OutfitKit. Es composición de un SplitPane (sidebar + main) + List de conversaciones + burbujas de mensajes. Consulta el ejemplo completo en examples/mini-apps/chat.html.
Composición: grid 280px / 1fr → sidebar =
Searchbar + List de Item con Avatar + Label; main = header con avatar + área scrolleable con burbujas (Card) alineadas a izq/dcha + Footer con Input + Button icon.
Layout completo · sidebar + thread
Operaciones
● 7 miembros · 3 en línea
Hoy
LP
Lucía Peña
Acabo de cerrar arqueo de caja 2. Cuadra al céntimo.
14:32
Perfecto, gracias. Mando informe.
14:33 ✓✓
<div style="display:grid;grid-template-columns:280px 1fr;height:520px;border:1px solid var(--line);border-radius:12px;overflow:hidden;width:100%">
<aside style="display:flex;flex-direction:column;border-right:1px solid var(--line);overflow:hidden">
<div style="padding:8px">
<div class="search"><iconify-icon icon="lucide:search"></iconify-icon><input class="input sm" placeholder="Buscar conversación…"/></div>
</div>
<div class="list" style="flex:1;overflow-y:auto">
<div class="item active" role="button">
<span class="avatar"><span class="avatar-initials">OP</span></span>
<div class="label"><div class="title sm">Operaciones</div><div class="sub">Lucía: Acabo de cerrar arqueo</div></div>
<span class="note">14:32</span>
</div>
<div class="item" role="button">
<span class="avatar"><span class="avatar-initials">EM</span></span>
<div class="label"><div class="title sm">Elena Marín</div><div class="sub">¿Has revisado la propuesta?</div></div>
<span class="note"><span class="chip brand sm">3</span></span>
</div>
<div class="item" role="button">
<span class="avatar"><span class="avatar-initials">JR</span></span>
<div class="label"><div class="title sm">Javi Ruiz</div><div class="sub">Tú: Perfecto, gracias</div></div>
<span class="note">12:20</span>
</div>
<div class="item" role="button">
<span class="avatar"><span class="avatar-initials">CN</span></span>
<div class="label"><div class="title sm">Café Norte</div><div class="sub">Confirmado: vamos con plan Pro</div></div>
<span class="note">lun</span>
</div>
</div>
</aside>
<section style="display:flex;flex-direction:column;overflow:hidden">
<header class="head" style="padding:12px 16px;border-bottom:1px solid var(--line)">
<span class="avatar"><span class="avatar-initials">OP</span></span>
<div class="heading"><div class="title sm">Operaciones</div><div class="meta success">● 7 miembros · 3 en línea</div></div>
</header>
<div style="flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:10px">
<div class="text-center meta">Hoy</div>
<div style="display:flex;gap:8px;align-items:flex-end">
<span class="avatar sm"><span class="avatar-initials">LP</span></span>
<div>
<div class="meta">Lucía Peña</div>
<div class="card" style="max-width:60ch;padding:10px 14px;background:var(--bg-2)">Acabo de cerrar arqueo de caja 2. Cuadra al céntimo.</div>
<div class="meta">14:32</div>
</div>
</div>
<div style="display:flex;justify-content:flex-end">
<div style="text-align:right">
<div class="card" style="max-width:60ch;padding:10px 14px;background:var(--brand-soft);color:var(--brand)">Perfecto, gracias. Mando informe.</div>
<div class="meta">14:33 ✓✓</div>
</div>
</div>
</div>
<footer class="foot" style="border-top:1px solid var(--line);padding:8px;display:flex;gap:8px;align-items:center">
<input class="input" placeholder="Escribe un mensaje…" style="flex:1"/>
<button class="btn brand icon"><iconify-icon icon="lucide:send" width="16"></iconify-icon></button>
</footer>
</section>
</div>
<div style="display:grid;grid-template-columns:280px 1fr;height:520px;border:1px solid var(--line);border-radius:12px;overflow:hidden">
<!-- Sidebar conversaciones -->
<aside style="display:flex;flex-direction:column;border-right:1px solid var(--line);overflow:hidden">
<div style="padding:8px">
<Searchbar placeholder="Buscar conversación…" />
</div>
<List attrs={"style": "flex:1;overflow-y:auto"}>
<Item attrs={"class": "active", "role": "button"}>
<Avatar label="OP" />
<Label><div class="title sm">Operaciones</div><div class="sub">Lucía: Acabo de cerrar arqueo</div></Label>
<Note>14:32</Note>
</Item>
<Item attrs={"role": "button"}>
<Avatar label="EM" />
<Label><div class="title sm">Elena Marín</div><div class="sub">¿Has revisado la propuesta?</div></Label>
<Note><Chip color="brand" size="sm">3</Chip></Note>
</Item>
<Item attrs={"role": "button"}>
<Avatar label="JR" />
<Label><div class="title sm">Javi Ruiz</div><div class="sub">Tú: Perfecto, gracias</div></Label>
<Note>12:20</Note>
</Item>
<Item attrs={"role": "button"}>
<Avatar label="CN" />
<Label><div class="title sm">Café Norte</div><div class="sub">Confirmado: vamos con plan Pro</div></Label>
<Note>lun</Note>
</Item>
</List>
</aside>
<!-- Thread -->
<section style="display:flex;flex-direction:column;overflow:hidden">
<header class="head" style="padding:12px 16px;border-bottom:1px solid var(--line)">
<Avatar label="OP" />
<div class="heading">
<div class="title sm">Operaciones</div>
<div class="meta success">● 7 miembros · 3 en línea</div>
</div>
</header>
<div style="flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:10px">
<div class="text-center meta">Hoy</div>
<!-- Mensaje recibido -->
<div style="display:flex;gap:8px;align-items:flex-end">
<Avatar label="LP" size="sm" />
<div>
<div class="meta">Lucía Peña</div>
<Card attrs={"style": "max-width:60ch;padding:10px 14px;background:var(--bg-2)"}>
Acabo de cerrar arqueo de caja 2. Cuadra al céntimo.
</Card>
<div class="meta">14:32</div>
</div>
</div>
<!-- Mensaje enviado -->
<div style="display:flex;justify-content:flex-end">
<div style="text-align:right">
<Card attrs={"style": "max-width:60ch;padding:10px 14px;background:var(--brand-soft);color:var(--brand)"}>
Perfecto, gracias. Mando informe.
</Card>
<div class="meta">14:33 ✓✓</div>
</div>
</div>
</div>
<footer class="foot" style="border-top:1px solid var(--line);padding:8px;display:flex;gap:8px;align-items:center">
<Input placeholder="Escribe un mensaje…" attrs={"style": "flex:1"} />
<Button icon="lucide:send" icon_only variant="brand" />
</footer>
</section>
</div>
<div style="display:grid;grid-template-columns:280px 1fr;height:520px;border:1px solid var(--line);border-radius:12px;overflow:hidden">
<!-- Sidebar conversaciones -->
<aside style="display:flex;flex-direction:column;border-right:1px solid var(--line);overflow:hidden">
<div style="padding:8px">
<Searchbar placeholder="Buscar conversación…" />
</div>
<List attrs={"style": "flex:1;overflow-y:auto"}>
<Item attrs={"class": "active", "role": "button"}>
<Avatar label="OP" />
<Label><div class="title sm">Operaciones</div><div class="sub">Lucía: Acabo de cerrar arqueo</div></Label>
<Note>14:32</Note>
</Item>
<Item attrs={"role": "button"}>
<Avatar label="EM" />
<Label><div class="title sm">Elena Marín</div><div class="sub">¿Has revisado la propuesta?</div></Label>
<Note><Chip color="brand" size="sm">3</Chip></Note>
</Item>
<Item attrs={"role": "button"}>
<Avatar label="JR" />
<Label><div class="title sm">Javi Ruiz</div><div class="sub">Tú: Perfecto, gracias</div></Label>
<Note>12:20</Note>
</Item>
<Item attrs={"role": "button"}>
<Avatar label="CN" />
<Label><div class="title sm">Café Norte</div><div class="sub">Confirmado: vamos con plan Pro</div></Label>
<Note>lun</Note>
</Item>
</List>
</aside>
<!-- Thread -->
<section style="display:flex;flex-direction:column;overflow:hidden">
<header class="head" style="padding:12px 16px;border-bottom:1px solid var(--line)">
<Avatar label="OP" />
<div class="heading">
<div class="title sm">Operaciones</div>
<div class="meta success">● 7 miembros · 3 en línea</div>
</div>
</header>
<div style="flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:10px">
<div class="text-center meta">Hoy</div>
<!-- Mensaje recibido -->
<div style="display:flex;gap:8px;align-items:flex-end">
<Avatar label="LP" size="sm" />
<div>
<div class="meta">Lucía Peña</div>
<Card attrs={"style": "max-width:60ch;padding:10px 14px;background:var(--bg-2)"}>
Acabo de cerrar arqueo de caja 2. Cuadra al céntimo.
</Card>
<div class="meta">14:32</div>
</div>
</div>
<!-- Mensaje enviado -->
<div style="display:flex;justify-content:flex-end">
<div style="text-align:right">
<Card attrs={"style": "max-width:60ch;padding:10px 14px;background:var(--brand-soft);color:var(--brand)"}>
Perfecto, gracias. Mando informe.
</Card>
<div class="meta">14:33 ✓✓</div>
</div>
</div>
</div>
<footer class="foot" style="border-top:1px solid var(--line);padding:8px;display:flex;gap:8px;align-items:center">
<Input placeholder="Escribe un mensaje…" attrs={"style": "flex:1"} />
<Button icon="lucide:send" icon_only variant="brand" />
</footer>
</section>
</div>
Install the Jinja addon and import the component:
pip install outfitkit
Then in your template:
{% from "<component>.jinja" import <component> %}
{{ <component>(...) }}
Or with JinjaX:
<Component ... />