<!-- Protocore Design System — InlineMessage -->
# InlineMessage

- **Category:** Feedback (`feedback`)
- **Slug:** `feedback/inline-message`
- **Status:** stable
- **Platforms:** web, mobile
- **Import:** `import { InlineMessage } from "@protocore/pds";`
- **Docs:** https://pds.protocore.io/components/feedback/inline-message

> A compact single-line status message — tone dot plus text — for field- and form-level feedback.

## InlineMessage vs. Banner vs. Callout vs. Toast

All four carry a tone, but they differ in weight and scope:

- **InlineMessage** — one line, tied to a specific control or row. Field validation, a row's save status. The lightest of the four.
- **[Callout](/feedback/callout)** — a tinted block of prose in the reading flow (a note, a caveat). It explains; it isn't tied to one control.
- **[Banner](/feedback/banner)** — a full-width, page- or section-level notice, optionally with an action or dismiss. It applies to the whole surface.
- **[Toast](/feedback/toast)** — a transient, self-dismissing confirmation of a discrete action, raised imperatively.

Rule of thumb: attached to a field → InlineMessage; spans the page → Banner; a note in the copy → Callout; a fleeting reaction → Toast.

## Mobile (React Native)

**Preview.** `@protocore/pds-mobile` ships the React Native sibling of **InlineMessage**. It mirrors the web API where React Native allows; the package is a **preview** with no device-level QA yet, so pin it and expect small changes.

Import it from the mobile package (not `@protocore/pds`), inside a `<PdsProvider>` — there is no stylesheet, so `style` (a `ViewStyle`) replaces `className` and every value comes from the theme:

```tsx
import { InlineMessage } from "@protocore/pds-mobile";
```

**Parity with web.** A one-line tone status row for inline / form feedback.

- A square tone dot (or your `icon`) followed by tone-coloured sans text at the metadata size.

```tsx
<InlineMessage tone="danger">Deploy failed — check the logs.</InlineMessage>
```

## Props

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `children` | `ReactNode` | no | — | Message text. |
| `className` | `string` | no | — | — |
| `icon` | `ReactNode` | no | — | Optional leading icon; replaces the default tone dot. |
| `style` | `CSSProperties` | no | — | — |
| `tone` | `enum` | no | `neutral` | Status tone; drives the dot color and text color. |

## Examples

### Basics

A `tone` and a line of text. A small dot in the tone color leads the message; the text picks up the matching foreground.

```tsx
import { InlineMessage } from "@protocore/pds";

export default function Basics() {
  return <InlineMessage tone="danger">Signature verification failed.</InlineMessage>;
}
```

### Tones

The five status tones — `success`, `warning`, `danger`, `info`, `neutral`. Keep the copy to a single line; this is a status, not a paragraph.

```tsx
import { InlineMessage, VStack } from "@protocore/pds";

export default function Tones() {
  return (
    <VStack gap={3} align="start">
      <InlineMessage tone="success">Node registered on-chain.</InlineMessage>
      <InlineMessage tone="warning">Stake below the recommended minimum.</InlineMessage>
      <InlineMessage tone="danger">RPC endpoint unreachable.</InlineMessage>
      <InlineMessage tone="info">Sync will resume from block 4 812 903.</InlineMessage>
      <InlineMessage tone="neutral">No pending withdrawals.</InlineMessage>
    </VStack>
  );
}
```

## Do & don't

**Do**

- Use it for field- and form-level status, one line at a time.
- Place it immediately below the control it refers to.
- Let the `tone` match the meaning (danger for errors, success for confirmations).
- Swap the dot for a custom `icon` when a glyph communicates faster.

**Don't**

- Pack multiple sentences into one InlineMessage — reach for a Callout.
- Use it for page-wide notices — that's a Banner.
- Rely on the tone color alone; the text must carry the meaning.
- Use it for transient action confirmations — that's a Toast.

## Accessibility

**Notes**

- The tone dot (or custom icon) is `aria-hidden`; the message text carries the meaning for every user.
- InlineMessage doesn't assume a live-region role — when it reports validation, wire it to the control via `aria-describedby` (the [Field](/inputs/field) wrapper does this for you).
- For dynamic errors that must be announced, render it inside a container you mark `role="alert"` or `aria-live`.
- Never encode status through color alone; the wording must stand on its own.

## Related

`banner`, `callout`, `toast`

---

© Protocore. All rights reserved. Use of the Protocore Design System requires prior written authorization from Protocore (contact@protocore.io). These machine-readable materials must not be ingested into ML-training datasets or derivative design systems. See https://pds.protocore.io/legal/
