Skip to content

DataPage - Details Panel

The details panel displays detailed information about the selected row in a resizable side panel.

Provide a detailsComponent prop to enable the details panel:

const ProductDetails = ({ item }) => (
<div className="p-4">
<h2>{item.name}</h2>
<p>{item.description}</p>
<div className="mt-4">
<p><strong>SKU:</strong> {item.sku}</p>
<p><strong>Price:</strong> ${item.price}</p>
<p><strong>Stock:</strong> {item.stock} units</p>
<p><strong>Category:</strong> {item.category}</p>
</div>
</div>
);
<DataPage
title="Products"
query={ProductsQuery}
emptyMessage="No products"
detailsComponent={ProductDetails}
>
{/* MenuItems and Columns */}
</DataPage>

Your detail component receives:

  • item: The selected data item
  • onRefresh: Optional callback — called when a refresh should be signalled back to the page (e.g. after a mutation in the detail panel)
interface IDetailsComponentProps<TDataType> {
item: TDataType;
onRefresh?: () => void;
}
const OrderDetails = ({ item }) => {
return (
<div className="order-details p-4">
<div className="header mb-4">
<h2>Order #{item.orderNumber}</h2>
<span className={`status-badge ${item.status}`}>
{item.status}
</span>
</div>
<div className="section mb-4">
<h3>Customer Information</h3>
<p><strong>Name:</strong> {item.customerName}</p>
<p><strong>Email:</strong> {item.customerEmail}</p>
<p><strong>Phone:</strong> {item.customerPhone}</p>
</div>
<div className="section mb-4">
<h3>Order Items</h3>
<table className="w-full">
<thead>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Price</th>
</tr>
</thead>
<tbody>
{item.items.map(orderItem => (
<tr key={orderItem.id}>
<td>{orderItem.name}</td>
<td>{orderItem.quantity}</td>
<td>${orderItem.price}</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="section">
<h3>Totals</h3>
<p><strong>Subtotal:</strong> ${item.subtotal}</p>
<p><strong>Tax:</strong> ${item.tax}</p>
<p><strong>Total:</strong> ${item.total}</p>
</div>
</div>
);
};

Wire the details component into the page:

<DataPage
title="Orders"
query={OrdersQuery}
emptyMessage="No orders"
detailsComponent={OrderDetails}
>
{/* ... */}
</DataPage>

Add interactive elements in the details panel:

const ProductDetails = ({ item }) => {
const [editing, setEditing] = useState(false);
return (
<div className="p-4">
<div className="flex justify-between items-center mb-4">
<h2>{item.name}</h2>
<Button
label={editing ? "Save" : "Edit"}
onClick={() => setEditing(!editing)}
/>
</div>
{editing ? (
<div>
{/* Edit form */}
<InputText value={item.name} onChange={...} />
</div>
) : (
<div>
{/* Display view */}
<p>{item.description}</p>
</div>
)}
</div>
);
};

The details panel is resizable by default using Allotment. Users can drag the divider to adjust the split.

To disable resizing, you would need to wrap the DataPage or use custom layout.

When no row is selected, the details panel is hidden automatically.

  1. Keep it focused: Display essential details, not everything
  2. Load additional data: Use the item ID to fetch related data if needed
  3. Provide actions: Include relevant actions (edit, delete, etc.) in the details panel
  4. Use tabs: For complex details, organize into tabs
  5. Show relationships: Display related items or hierarchical data
  6. Include metadata: Creation dates, last modified, version info
  7. Make it actionable: Add buttons for common operations
  8. Consider performance: Lazy load heavy content or images