Availability Row
- Stable
- WCAG 2.2 evidence
- RTL
One person's availability across a window of the day: an avatar with initials and the name,
and a timeline with the busy periods drawn as bars. Presentational: renders in React Server Components, no React Aria. The row is a named group (role="group", named by the person). The timeline is an image with a text alternative
("Busy 9:00 AM to 10:30 AM and Out of office 1:00 PM to 3:00 PM", or "Free all day"), so the information is not only in
the colours; out-of-office bars also carry stripes (WCAG 1.1.1, 1.4.1). Bars are placed from the inline start edge and
mirror in right-to-left locales. Narrow containers stack the person above the timeline (1.4.10). Consumer duties: time zones, keeping the window and the periods in the same zone, and a visible legend or heading when a
list of rows needs one.
import { AvailabilityRow } from "@nexera-ui/react";- 6
- examples
- 8
- props
- 0
- live controls
- 1
- platform
- 6
- WCAG criteria
- 1
- block uses it
Try every prop. Copy the code.
Change the props and the code updates. Check light and dark, LTR and RTL, and phone width.
import { AvailabilityRow } from "@nexera-ui/react";
<AvailabilityRow />Examples 5
The same examples as Storybook, rendered live. Open Code to copy one.
Free
A person with nothing in the window: the timeline is empty and its text alternative says "Free all day".
import { AvailabilityRow } from "@nexera-ui/react";
const at = (hour: number, minute = 0) => new Date(Date.UTC(2026, 9, 14, hour - 5, minute));
const rangeStart = at(8);
const rangeEnd = at(18);
<AvailabilityRow
name="Ayesha Khan"
rangeStart={rangeStart}
rangeEnd={rangeEnd}
segments={[]}
locale="en-US"
timeZone="Asia/Karachi"
/>;
Team
Several people on one window. Each row is a named group; the rows share the 180 px name column so the timelines line up.
import { AvailabilityRow } from "@nexera-ui/react";
const at = (hour: number, minute = 0) => new Date(Date.UTC(2026, 9, 14, hour - 5, minute));
const rangeStart = at(8);
const rangeEnd = at(18);
const saraSegments: AvailabilitySegment[] = [
{ start: at(9), end: at(10, 30) },
{ start: at(12), end: at(13) },
{ start: at(15), end: at(17), type: "out-of-office" },
];
const team = [
{ name: "Sara Malik", segments: saraSegments },
{
name: "Ayesha Khan",
segments: [
{ start: at(8), end: at(9, 30) },
{ start: at(14), end: at(15, 30) },
],
},
{
name: "Bilal Ahmed",
segments: [{ start: at(10), end: at(18), type: "out-of-office" as const }],
},
{ name: "Zara Siddiqui", segments: [] },
];
export function Team() {
return (
<ul
aria-label="Team availability on Wednesday 14 October"
className="m-0 flex list-none flex-col p-0"
>
{team.map((person) => (
<li key={person.name}>
<AvailabilityRow
rangeStart={rangeStart}
rangeEnd={rangeEnd}
locale="en-US"
timeZone="Asia/Karachi"
name={person.name}
segments={person.segments}
/>
</li>
))}
</ul>
);
}
Long name
A long name wraps inside its 180 px column; it is never truncated.
import { AvailabilityRow } from "@nexera-ui/react";
const at = (hour: number, minute = 0) => new Date(Date.UTC(2026, 9, 14, hour - 5, minute));
const rangeStart = at(8);
const rangeEnd = at(18);
const saraSegments: AvailabilitySegment[] = [
{ start: at(9), end: at(10, 30) },
{ start: at(12), end: at(13) },
{ start: at(15), end: at(17), type: "out-of-office" },
];
<AvailabilityRow
name="Muhammad Abdul Rahman bin Abdul Aziz Al-Fahad"
rangeStart={rangeStart}
rangeEnd={rangeEnd}
segments={saraSegments}
locale="en-US"
timeZone="Asia/Karachi"
/>;
Right to left
Right-to-left (Arabic): the avatar and name start at the right, and the day runs right to left, so 08:00 is at the right edge.
import { AvailabilityRow } from "@nexera-ui/react";
const at = (hour: number, minute = 0) => new Date(Date.UTC(2026, 9, 14, hour - 5, minute));
const rangeStart = at(8);
const rangeEnd = at(18);
const saraSegments: AvailabilitySegment[] = [
{ start: at(9), end: at(10, 30) },
{ start: at(12), end: at(13) },
{ start: at(15), end: at(17), type: "out-of-office" },
];
<AvailabilityRow
name="سارة مالك"
rangeStart={rangeStart}
rangeEnd={rangeEnd}
segments={saraSegments}
locale="ar-EG"
timeZone="Asia/Karachi"
initials="سم"
labels={{ busy: "مشغول", outOfOffice: "خارج المكتب", to: "إلى", free: "متاح طوال اليوم" }}
/>;
Narrow container
Below 480 px of container width the person stacks above the timeline.
import { AvailabilityRow } from "@nexera-ui/react";
const at = (hour: number, minute = 0) => new Date(Date.UTC(2026, 9, 14, hour - 5, minute));
const rangeStart = at(8);
const rangeEnd = at(18);
const saraSegments: AvailabilitySegment[] = [
{ start: at(9), end: at(10, 30) },
{ start: at(12), end: at(13) },
{ start: at(15), end: at(17), type: "out-of-office" },
];
<div className="max-w-80 border border-dashed border-default">
<AvailabilityRow
name="Sara Malik"
rangeStart={rangeStart}
rangeEnd={rangeEnd}
segments={saraSegments}
locale="en-US"
timeZone="Asia/Karachi"
/>
</div>;
Props 8
8 props shown
name*NexerastringThe person. Names the row, and wraps instead of truncating.
initialsNexerastringLetters in the avatar circle. Decorative: the name carries the meaning.
rangeStart*NexeraDateStart of the window the timeline covers, for example 08:00 (an instant).
rangeEnd*NexeraDateEnd of the window the timeline covers, for example 18:00 (an instant).
segmentsNexerareadonly AvailabilitySegment[]The busy periods inside the window. Each is placed by its share of the window and listed in the timeline's text alternative with its times. Periods outside the window are left out.
localeNexerastringBCP 47 locale for the times in the text alternative. Pass the same locale on the server and in the browser: without it the runtime locale is used, and server and browser can differ.
timeZoneNexerastringIANA time zone the times are read in (for example Asia/Karachi). Without it the viewer's time zone is used.
labelsNexeraPartial<AvailabilityRowLabels>Translate the words of the text alternative.
* Required. React Aria props shown are the ones most apps use; the component accepts the rest of its React Aria props too.
Accessible by default.
Built on React Aria, and covered by the WCAG 2.2 evidence generated on every build.
WCAG 2.2 evidence
4 direct · 2 supporting- 1.1.1Non-text ContentLevel A · tested directly
- 1.3.1Info and RelationshipsLevel A · tested directly
- 1.4.1Use of ColorLevel A · tested directly
- 1.4.10ReflowLevel AA · supporting test
- 1.4.12Text SpacingLevel AA · supporting test
- 4.1.2Name, Role, ValueLevel A · tested directly
Fits any width.
Nexera components respond to the space they are given. Drag the corner of the frame, or pick a width.
Styling hooks
Pass className to add Tailwind classes (merged last). State is exposed as data attributes, so you can style it with variants like data-pressed:.
<AvailabilityRow className="shadow-sm" />Used in blocks
Related components
- AccordionItemOne collapsible section of an FAQ or settings page.
- AreaChartA stacked area chart: layers piled up over time with the title, range switch, actions and legend of the card.
- AvatarA person or organisation shown as a photo, initials or an icon.
- AvatarGroupA row of overlapping avatars with a "+N" chip for the rest.
- AvatarLabelAn avatar with a name and an optional subtitle beside it, for a person in a list, a header or a mention.
- BadgeShort status or category label: `Tone` x `Variant` x `Size`, with an optional dot, leading icon and remove button.
- BadgeGroupA pill that pairs a small badge with a short message, for an announcement or a status line.
- BadgeOverflowThe "+N" pill that stands in for the badges a row has no room for.