List and detail
A list beside the record chosen from it. Side by side on a larger screen, one at a time on a phone.
Usage
import { ListDetail, ListDetailBack, ListDetailDetail, ListDetailList } from "@cadence-clinical/ui";
function Referrals() {
const [openId, setOpenId] = useState<string | null>(null);
return (
<ListDetail open={openId !== null} onBack={() => setOpenId(null)}>
<ListDetailList aria-label="Referrals">...</ListDetailList>
<ListDetailDetail aria-label="Referral">
<ListDetailBack>All referrals</ListDetailBack>
...
</ListDetailDetail>
</ListDetail>
);
}Most clinical work is a list beside the record chosen from it: referrals, results, appointments. List and detail is the layout for it. It holds no content of its own: the list, the record and how a record is chosen are yours.
shadcn has no component for this. Put the list's rows in Items, and show an Empty where no record is open.
The parts
ListDetailholds the two. Setopenwhile a record is shown, and clear the record inonBack.ListDetailListis the list, asection. Name it witharia-label, so it is a region a screen reader can move to.ListDetailDetailis the record, asectiontoo. Name it as well.ListDetailBackis a Button that brings the list back on a phone. It is not shown frommdup, where the list is in view. Name it by the list, such as "All referrals".
Mark the row of the open record with aria-current="true", so a screen reader says which one is open.
Side by side, and one at a time
From the md breakpoint up, the list and the record sit side by side, and each scrolls on its own. The list is between 16rem and 22rem wide, and the record takes the rest. Inside an Application shell, the layout fills the height under the header. Elsewhere, set its height with className.
On a phone, one shows at a time. While open, the record takes the list's place, focus moves to it, and the page scrolls to the record's top, below a sticky header such as the Application shell's, however far down the list was scrolled. ListDetailBack brings the list back, with focus on the row that had it.
Accessibility
- Named with
aria-label, each part is a region a screen reader can move to. - On a phone, focus follows the part that is shown, so a screen reader starts reading the record when it opens, and returns to the list where it left it.
- A part that is not shown is hidden from assistive technology as well as from sight.
Props
| Prop | On | Type | Default |
|---|---|---|---|
open | ListDetail | boolean | false |
onBack | ListDetail | () => void |