Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Email Compose Skeleton Block for Radix UI

A saved email draft that loads in place: boxes become the To, Cc and Subject fields and an editable body, with working Bold, Italic and List toggles and a Send that sends nothing.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Show a composer while its draft loads, then swap the fields in without moving anything, with this email compose skeleton for React with Radix UI. A hairline frame with a plus mark on each corner holds a saved draft in Alembic, an outreach-email tool, in four bands: the To, Cc and Subject fields, a formatting toolbar, the body and a foot with Send and Save draft. The labels, the toolbar and both buttons are real from the first paint; the three values and the body are Skeleton boxes that become the real, editable fields in the same place. Bold and Italic style the whole body and List turns every line into a list item, all in this tab. Send and Save draft say that nothing was sent or saved. It's built from Skeleton, Field, Input, Textarea, Toggle, Shine Button and Guides, with a CSS entrance only. For composers, reply boxes and any form that opens prefilled.

FAQ

What stays local, and how do I wire it to a real draft?

Nothing is fetched. The draft's fields are typed in DRAFT, Load starts a 700 millisecond timer, and when it ends the phase becomes ready and the data swaps in; Reload goes back to the bars and in again. To wire it for real, delete the timer, the Load button and the polite line, and set data-state (loading or ready) and aria-busy on the region from your query's pending state, or use the bars as a Suspense fallback and render the real fields when they arrive. The bars are derived from the same data as the content, so keep one component for both. Send and Save draft only set the polite line: call your own endpoints from send and save.

Does the composer keep its height while it loads?

Each bar and its content sit in one grid cell, so the larger of the two sets the cell's box and the swap changes nothing around it. Each field is a bar the height of an input in the same cell as the input, and the body has a fixed height (h-56, with field-sizing-fixed), so typing never grows it. The chrome is real in both phases and the polite line reserves two lines, so the panel is exactly as tall before, during and after loading at every width.

What do Bold, Italic and List do?

Bold and Italic change the weight and style of the whole body, so the effect is visible but not saved. List adds a dash to the start of every non-empty line and takes them off again when you turn it off. They are disabled while the draft loads.

Can I edit the loaded draft?

Yes. The fields are real controlled inputs holding the typed draft, so what you type stays until you press Reload, which restores the draft.

Is it accessible?

The region is marked busy while it loads and carries a screen-reader-only "Loading draft…", and the polite line announces what loaded once. The bars are hidden from assistive technology and the layer that isn't showing is invisible, so it is neither read nor focusable. The pulse stops when the data is in, and under reduced motion there is no pulse, no spinner and no stagger: the swap is instant. Every field has a visible label, the toolbar is a labelled group, and the body has its own label.