Information blocks

Information blocks

The vocabulary every Yuno detail screen is read from. form-field is how a screen ASKS for data; this is how it SHOWS it. Payment details, a reconciliation run, an API key, a seller, an audit event: anything the Dashboard reflects back from an API is read through these pieces, which is why they are not a payments component.

Updated Aug 27, 2026 by Juan Pablo Turina

Anatomy

A field is a label over or beside a value. The label is semibold foreground and the value is muted — inverted from a form, and the single easiest thing to get backwards. In a form the label is quiet and what you typed is the ink; here you are scanning for the field you want among thirty, not reading prose.

Payment ID
50af22fc-2eb1-4a9f-8c8f-9458649603c2
  1. 1
    Label

    14/20 semibold foreground. The strong half.

  2. 2
    Copy

    Optional, beside the label. On a sensitive field it MOVES into the action cluster.

  3. 3
    Value

    14/20 regular muted. A string, or anything you hand it as children: a StatusBadge, a CountryCell, a payment method, a row of chips.

The four shapes

A list has four shapes and each answers a different question about the DATA, not about the width. Horizontal puts the label beside the value and lines every value up on one edge, which is what keeps thirty fields scannable — it is the default a detail screen wants. Vertical stacks the label over the value, for values too long or too unlike to share a column. Drawer is a Sheet, where the value goes hard against the right edge and never wraps. Separated puts a rule between every field, for a panel whose values have nothing in common.

Payment ID
50af22fc-2eb1-4a9f-8c8f-9458649603c2
Order ID
1668010758843
Status
Succeeded
Country
Colombia (CO)
{/* Horizontal — the default a detail screen wants. */}
<InfoList>
  <InfoField label="Payment ID" value={id} copyable />
  <InfoField label="Status"><StatusBadge status="succeeded" /></InfoField>
</InfoList>

{/* Vertical — the label stacked over its value. */}
<InfoList orientation="vertical">…</InfoList>

{/* Separated — a rule between fields whose values are unlike. */}
<InfoList separated>…</InfoList>

Values a role gates

Some data cannot be shown to everyone. It travels masked and only a specific role reveals it — and a sensitive field is a DIFFERENT COMPOSITION, not the same field with an eye added: the copy leaves the label and joins the eye in a cluster on the right, with a rule between them. The gate is real, not decorative. Masked, the copy is disabled, because copying a secret you are not allowed to read hands it over anyway. Revealed, the glyph opens and the copy lifts to foreground. With no role there is no cluster at all — an eye that cannot reveal and a copy that cannot copy are two dead controls, and someone without the role always sees the masked value. The mask itself is yours: which clue survives is a decision per field.

Name
John Doe
Email
j••••••@example.com
Tax ID
•••••6789
Phone
+1 ••• ••• 4532
{/* The mask is yours — which clue survives is a decision per field. */}
<InfoField
  label="Tax ID"
  value={taxId}
  masked="•••••6789"
  canReveal={user.can("pii.read")}
/>

{/* No role: always masked, and no cluster at all. */}
<InfoField label="Phone" value={phone} masked="+1 ••• ••• 4532" />

In a Sheet

A Sheet is its own set in the Figma, not a narrower page. There are exactly two shapes and which one you get follows from the column count: one column is a row per field with the value against the right edge, for few fields or long values; two columns stack the label over its value, for many short fields where one row each would make a very long panel. Either way the value stays on ONE line and truncates, and the whole of it comes back in a Tooltip. And the fields are never bare against the panel — they live in the same InfoBlock card as on a page.

<SheetBody>
  <InfoBlock title="General">
    <InfoList drawer columns={1}>
      <InfoField label="Entity ID" value={entityId} copyable />
    </InfoList>
  </InfoBlock>
</SheetBody>

The card

InfoBlock is the card a group of fields sits in, and it is not optional chrome. The same card serves a page and a Sheet; inside a Sheet the body supplies its own padding around it. Its heading takes the kit's Title atom.

Seller detail

Key name
restricted_prueba
Member with access
Margarita RodriguezSaimon RevichRamiro Peña
Created date
Feb 8, 2025, 10:00 a.m.
<InfoBlock title="Seller detail">
  <InfoList separated>
    <InfoField label="Key name" value="restricted_prueba" />
    <InfoField label="Member with access">
      <div className="flex flex-wrap gap-2">
        <Badge variant="secondary">Margarita Rodriguez</Badge>
      </div>
    </InfoField>
  </InfoList>
</InfoBlock>

One card, several groups

A block can hold more than one named run of fields — General, then Payment method, then Customer — and it can fold. Each section carries its own leading rule rather than the block spacing them out: the Figma puts one above every section including the first, so the header is divided from its content by the same device, and a section that owns its rule can be dropped anywhere without the caller counting which one is first. It opens OPEN, and should stay that way: the Figma draws a CaretUp, and a caret pointing up means fold me, not unfold me. A detail block that opens folded hides what the reader came for. The whole header is the control, because a 16px glyph is a small target and a header carrying a caret already reads as one.

General

Account ID
50af22fc-2eb1-4a9f-8c8f-9458649603c2
Created at
Mon, Jan 5, 2026, 17:02:10 GMT-3
Description
Test
Country
Colombia (CO)

Payment method

Brand
Visa
Holder name
Pepito Perez
Last 4 digits
1111
Expiration date
3/26
<InfoBlock title="Seller detail" collapsible>
  <InfoSection title="General">
    <InfoList>…</InfoList>
  </InfoSection>
  <InfoSection title="Payment method">
    <InfoList>…</InfoList>
  </InfoSection>
</InfoBlock>

The top of a detail screen

Three tiers, and the order is the argument: the number you came for, the handful of facts that qualify it, then the identifiers you need once you have decided to care. A detail screen that opens with a grid of IDs makes you hunt for the amount. The summary strip is separated by vertical rules and the identifiers by a horizontal one — the same device at two scales, which is what keeps a block this dense from reading as a wall. The identifiers FLOW: as many per line as fit, wrapping onto the next.

$52.000,00 COP

Captured
$22.000,00 COP
Refunded
$10.000,00 COP
Status
Succeeded
Substatus
Refunded
Payment ID
50af22fc-2eb1-4a9f-8c8f-9458649603c2
Order ID
1668010758843
Creation date
Thursday, May 11, 2025, 10:25:49 GMT-6
Customer ID
4ce6f7e1-bf2e-4e7f-bc1b-84b26082a1d3
Country
Colombia (CO)
<PrincipalBlock
  headline="$52.000,00"
  headlineSuffix="COP"
  actions={<Button variant="outline" size="sm">Download</Button>}
  summary={[
    <InfoField key="c" label="Captured" value="$22.000,00 COP" />,
    <InfoField key="s" label="Status"><StatusBadge status="succeeded" /></InfoField>,
  ]}
  details={[
    <InfoField key="p" label="Payment ID" value={id} copyable />,
  ]}
/>

Import

Copy this import at the top of the file where you compose these.

import {
  InfoField,
  InfoList,
  InfoBlock,
  PrincipalBlock,
} from "@/components/patterns/info-block";