AI
Composer with attachments
Message field with files coming in and out.
Example
Main
project-mar
report.pdf
budget.xlsx
Hi, what do you need today?
Composer attachments
File cards slide in one by one above the prompt, with a thumbnail and a remove button.
<article class="u-ai-card">
<div class="u-ai-card__panel" data-u="ai-composer" role="group" aria-label="Demo: composer attachments">
<div class="u-ai-composer__ctx">
<span><svg class="u-ai-ico" viewBox="0 0 24 24" aria-hidden="true"><circle cx="6" cy="5" r="2"/><circle cx="6" cy="19" r="2"/><circle cx="18" cy="9" r="2"/><path d="M6 7v10M18 11c0 4-6 3-12 6"/></svg>Main</span>
<span><svg class="u-ai-ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg>project-mar</span>
</div>
<div class="u-ai-tile u-ai-composer__box">
<div class="u-ai-composer__files">
<div class="u-ai-file u-ai-file--img u-ai-x">
<svg class="u-ai-thumb" viewBox="0 0 76 76" aria-hidden="true">
<defs><linearGradient id="u-ai-sky" x1="0" y1="0" x2="0" y2="1"><stop offset="0" style="stop-color:var(--c2)"/><stop offset="1" style="stop-color:var(--c1)"/></linearGradient></defs>
<rect width="76" height="76" rx="12" fill="url(#u-ai-sky)"/>
<circle cx="52" cy="25" r="9" style="fill:var(--card)" opacity=".85"/>
<path d="M0 58 24 36 44 54 58 42 76 58v18H0z" style="fill:var(--c3)"/>
<path d="M0 66 20 54 40 66 60 56 76 66v10H0z" style="fill:var(--c5)" opacity=".85"/>
</svg>
<button class="u-ai-file__x" type="button" aria-label="Remove landscape.png"><svg class="u-ai-ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18"/></svg></button>
</div>
<div class="u-ai-file u-ai-x">
<span class="u-ai-file__kind u-ai-file__kind--pdf"><svg class="u-ai-ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M7 3h7l5 5v13H7z"/><path d="M14 3v5h5"/></svg></span>
<span class="u-ai-file__name">report.pdf</span>
<button class="u-ai-file__x" type="button" aria-label="Remove report.pdf"><svg class="u-ai-ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18"/></svg></button>
</div>
<div class="u-ai-file u-ai-x">
<span class="u-ai-file__kind u-ai-file__kind--xls"><svg class="u-ai-ico" viewBox="0 0 24 24" aria-hidden="true"><rect x="4" y="5" width="16" height="14" rx="2"/><path d="M4 10h16M4 14.5h16M10 5v14"/></svg></span>
<span class="u-ai-file__name">budget.xlsx</span>
<button class="u-ai-file__x" type="button" aria-label="Remove budget.xlsx"><svg class="u-ai-ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18"/></svg></button>
</div>
</div>
<div class="u-ai-composer__input">Hi, what do you need today?</div>
<div class="u-ai-composer__bar">
<button class="u-ai-composer__plus" type="button" aria-label="Add attachment"><svg class="u-ai-ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg></button>
<span class="u-ai-composer__chip"><svg class="u-ai-ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 3l7 3v5c0 5-3 8-7 10-4-2-7-5-7-10V6z"/><path d="M9 12l2 2 4-4"/></svg>Go through everything</span>
</div>
</div>
</div>
<div class="u-ai-card__text">
<h3 class="u-ai-card__title">Composer attachments</h3>
<p class="u-ai-card__desc">File cards slide in one by one above the prompt, with a thumbnail and a remove button.</p>
</div>
</article>Installation
Composer with attachments ships in the full package, along with the skill:
curl -fsSL unslop.leallabs.dev/i | shThe example HTML, to paste:
curl -fsSL unslop.leallabs.dev/i | sh -s add ai-composerUses The block is just HTML. The CSS and JS come from the full package's unslop.css and unslop.js.
Classes and variants
| Class | What it does |
|---|---|
.u-ai-composer__ctx | Attachment row. |
.u-ai-composer__box | Message box. |
.u-ai-file | Attachment: --img for images, __name, __x to remove. |
Accessibility and keyboard
State and roles
| Where | Attribute | What it says |
|---|---|---|
.u-ai-card__panel | role="group" and aria-label | Says it's a demo and of what. |
| remove | __x button | Removes the attachment with a transition. |
Keyboard
| Key | Does |
|---|---|
| Tab | enters the card and pauses the animation while focus is there |
Motion
Plays on its own when it enters the viewport, for up to 3 cycles, and stops in its final state. Hovering or focusing inside pauses it. With reduced motion, it shows the final state right away.
Events and API
No public events. For a real chat, copy the markup and wire up your own state, without relying on data-u for logic.