ViewOnly
The ViewOnly component displays data as read-only label-value pairs. It supports single-column and responsive two-column layouts, horizontal or vertical item layouts, loading states, and custom React content for any value.
Variations
Single column layout
Force a single-column layout regardless of container width with layout="singleColumn".
Two-column layout
By default the component uses a responsive two-column layout when the container is wide enough (≥800px), automatically splitting the data between the two columns.
Loading state
Display skeleton placeholders while data is being fetched.
Empty values
When a value is empty, null, or undefined, the component displays “empty” in a disabled style.
Custom value content
Values can be any React node, allowing for custom formatting and components.
Using ViewOnlyItem directly
Use the ViewOnlyItem component directly for more control over layout.
Installation
import { ViewOnly } from "@harnessio/ui/components";
<ViewOnly title="Section Title" data={[ { label: "Label 1", value: "Value 1" }, { label: "Label 2", value: "Value 2" }, ]}/>;Anatomy
ViewOnly renders an optional title above a description list of label-value pairs.
- The title renders as a heading; each entry is a
ViewOnlyItemshowing alabeland itsvalue. layoutcontrols the column mode:columns(default) switches to two columns once the container measures ≥800px wide, splitting the data between them;singleColumnalways stacks in one column.itemLayoutcontrols each pair’s own orientation:horizontal(default) places the label and value side by side;verticalstacks the label above the value.- Pass
forceColumnsto render two columns without measuring the container. - Each
valueaccepts any React node, so you can drop in badges, links, or formatted text.
Best practices
Do
- Use
ViewOnlyfor read-only summaries — profile details, run metadata, settings review — where fields don’t need editing. - Keep
labeltext short and consistent so the columns align cleanly. - Reach for
layout="singleColumn"in narrow containers (side panels, drawers) where two columns would cramp the values.
Don’t
- Don’t use
ViewOnlyfor editable data — it renders values as static text, not form fields. - Don’t rely on
0orfalsedisplaying literally; a falsy value shows “empty”.
Accessibility
Labeling & semantics
- In the default
horizontalitem layout, the component renders a description list: the container is a<dl>, each label a<dt>, and each value a<dd>, so assistive tech reads each value as the definition of its label. - Long string values are truncated with a native
titletooltip exposing the full text. Custom React-node values are not truncated or titled. - The
verticalitem layout renders labels and values as plain text rather than<dt>/<dd>; prefer the defaulthorizontallayout when description-list semantics matter.
Properties
ViewOnly
Prop | Required | Default | Type |
|---|---|---|---|
| data | true | ViewOnlyItemData[] | |
| title | false | string | |
| layout | false | 'columns' | 'singleColumn' | 'columns' |
| itemLayout | false | 'horizontal' | 'horizontal' | 'vertical' |
| forceColumns | false | false | boolean |
| isLoading | false | false | boolean |
| className | false | string |
ViewOnlyItem
Prop | Required | Default | Type |
|---|---|---|---|
| label | true | string | |
| value | true | ReactNode | |
| itemLayout | false | 'horizontal' | 'horizontal' | 'vertical' |
| isLoading | false | false | boolean |
ViewOnlyItemData
Type definition for each entry in data.
type ViewOnlyItemData = { label: string; value: ReactNode } | ReactNode;