Foundations
Identity primitives — the elements every screen leans on.
Icons
Font Awesome 7 Pro glyphs, referenced directly — this kit has no Icon wrapper.
Sizes
Regular vs Solid
Reference glyphs
import { faBell } from "@fortawesome/pro-regular-svg-icons";
import { faBellSolid } from "@fortawesome/pro-solid-svg-icons";
<FontAwesomeIcon icon={faBell} style={{ fontSize: 20 }} />icon:IconDefinitionstyle={{ fontSize }}:numberLogo
FMX brand mark — size × color variants.
<Logo size="lg" color="primary" />size:"default" | "lg"= "default"color:"primary" | "neutral"= "primary"label:stringAvatar
Circular avatar with sm (24×24) or md (40×40) size. Initials as fallback.
<Avatar size="md" initials="AG" />size:"sm" | "md"= "md"src:stringinitials:string= "?"showPlaceholder:boolean= falsealt:stringDisplay
Status indicators, rules, and notification dots.
Badge
solid/soft/surface/outline × default/sm + leading icon. Semantic colors apply to solid and soft.
<Badge type="solid" color="success">Approved</Badge>type:"solid" | "soft" | "surface" | "outline"= "solid"size:"default" | "sm"= "default"color:"neutral" | "success" | "primary" | "accent" | "error" | "warning"= "neutral"icon:IconDefinitionChip
Compact interactive token. Leading icon or avatar; optional remove button.
<Chip icon={faFilter} removable onRemove={() => setValue(null)}>
Active
</Chip>icon:IconDefinitionavatarInitials:stringremovable:boolean= falseonRemove:() => voiddisabled:boolean= falseDivider
1px border-muted rule. Horizontal fills width; vertical fills parent height.
<Divider direction="horizontal" />direction:"horizontal" | "vertical"= "horizontal"Notification
Dot (sm) or count bubble (lg). high=orange fill, low=primary blue.
<Notification count={3} priority="high" />size:"sm" | "lg"= "lg"priority:"high" | "low"= "high"count:number | stringOverlays
Hover and focus surfaces that float above the page.
Tooltip
Plain hover/focus tooltip. Wraps any trigger; placement controlled by location prop.
<Tooltip label="Help text" location="above">
<button>…</button>
</Tooltip>label:ReactNodelocation:"above" | "below" | "left" | "right"= "above"children:ReactNodeSheet
Side panel with header (title + description + close), scrollable body, optional footer.
Request details
Review and update the maintenance request.
Body content goes here — form fields, item details, etc.
Filters
Filter controls here.
<Sheet title="Filters" onClose={close}>
<FilterForm />
</Sheet>title:stringdescription:stringside:"right" | "left"= "right"showCloseButton:boolean= trueonClose:() => voidfooter:ReactNodechildren:ReactNodeForm controls
Inputs designers reach for when capturing data.
Input
Pseudo-class states (hovered, focused) appear on interaction.
<Input placeholder="Your name" />error:boolean= falsedisabled:boolean= falseplaceholder:stringvalue / defaultValue:stringInput Group
Input with leading/trailing icon or text adornment. Container picks up focus styling.
<InputGroup
leadingText="$"
placeholder="0.00"
trailingText="USD"
/>leadingIcon:IconDefinitionleadingText:stringtrailingIcon:IconDefinitiontrailingText:stringmenu:ReactNodeerror:boolean= falsedisabled:boolean= falseText Area
Multi-line input. Resize handle appears bottom-right; disabled removes it.
<TextArea placeholder="What's wrong?" />error:boolean= falsedisabled:boolean= falseplaceholder:stringvalue / defaultValue:stringSelect
Single-select dropdown — read-only trigger, no typing (use Combobox for that). Options can carry icon or avatar.
<Select
options={[{ value: "lobby", label: "Lobby" }]}
defaultValue="lobby"
/>options:SelectOption[]value / defaultValue:string | nullonChange:(value: string) => voidplaceholder:string= "Select something"error:boolean= falsedisabled:boolean= falseCombobox
Single- and multi-select. Click to open; type to filter. Options can carry icon or avatar. The listbox is viewport-aware — it caps its height to the available space and flips above the field near the bottom of the window.
<Combobox
value={value}
onChange={setValue}
options={ROOM_OPTIONS}
placeholder="Select a room"
/>options:ComboboxOption[]value:string | string[] | nullonChange:(next) => voidmultiple:boolean= falseclearable:boolean= falseplaceholder:stringleadingIcon:IconDefinitionerror:boolean= falsedisabled:boolean= falseCheckbox
state (default/error/disabled) × isChecked (yes/no) × isGrouped (yes/no) = 12 variants. Click any to toggle.
Optional helper text
Optional helper text
Optional helper text
Optional helper text
Optional helper text
Optional helper text
Optional helper text
Optional helper text
Optional helper text
Optional helper text
Optional helper text
Optional helper text
<Checkbox
label="I agree"
description="Required to proceed"
/>checked:booleandefaultChecked:boolean= falseonChange:(e) => voiderror:boolean= falsedisabled:boolean= falsegrouped:boolean= falselabel:ReactNodedescription:ReactNodeForm composition
Higher-order wrappers that arrange leaf components into real screens.
Field
Composes label + content + description (and error). Vertical or horizontal layout.
Choose the building this request applies to.
Building is required.
Pick the building this request applies to.
<Field>
<Field.Label required>Building</Field.Label>
<Field.Content>
<Combobox … />
</Field.Content>
</Field>fieldLayout:"default" | "horizontal"= "default"contentLayout:"default" | "horizontal"= "default"hasError:boolean= false(slots):Field.Label / .DescriptionTop / .Content / .Description / .ErrorField Set
Groups related Fields with a heading and optional description.
Location
Where is the issue you're reporting?
Optional — helps the technician find it faster.
<FieldSet>
<FieldSet.Heading>Location</FieldSet.Heading>
<FieldSet.Fields>
<Field>…</Field>
</FieldSet.Fields>
</FieldSet>(slots):FieldSet.Heading / .Description / .FieldsForm
Full prototype-grade form composed of Form + FieldSet + Field + leaf components.
<Form onSubmit={handleSubmit}>
<Form.Heading>Title</Form.Heading>
<Form.Content>…</Form.Content>
<Form.Footer>…</Form.Footer>
</Form>onSubmit:(e) => void(slots):Form.Heading / .Content / .FooterFeedback
Error and status banners.
Alert
Callout banner in five type variants — tinted container + border with a matching leading icon; text stays on-surface.
<Alert type="error" title="Couldn't save changes">
Check the highlighted fields.
</Alert>type:"general" | "success" | "info" | "warning" | "error"= "general"title:ReactNode= "Title"showTitle:boolean= truechildren:ReactNodeChrome
Page-level wrappers — navbar, sidebar, heading bars, breadcrumbs.
Toolbar
Search input + optional leading filter actions + trailing table-level action buttons.
<Toolbar searchPlaceholder="Search…">
<IconButton icon={faDownload} type="ghost" aria-label="Export" />
</Toolbar>searchPlaceholder:string= "Search..."searchValue:stringonSearchChange:(value: string) => voidleadingActions:ReactNodechildren:ReactNodePage Heading
Per-page title bar — optional leading icon, badge, description, icon-button cluster, action buttons, and a tabs row.
Maintenance requests
Request #4287
Reported 2 days ago · Lobby HVAC
Building 4
<PageHeading
icon={faWrench}
title="Request #4287"
badge={<Badge type="surface">In progress</Badge>}
buttons={<Button>Save</Button>}
tabs={
<>
<PageHeading.Tab active>Overview</PageHeading.Tab>
<PageHeading.Tab>Requests</PageHeading.Tab>
</>
}
/>title:stringicon:IconDefinitionbadge:ReactNodedescription:stringiconButtons:ReactNodebuttons:ReactNodetabs:ReactNodeSection Heading
In-page section header with title, optional description, and trailing actions.
<SectionHeading
title="Location details"
description="Where the issue was reported."
/>title:stringdescription:stringactions:ReactNodeScheduling
Date and time selection.
Calendar
Single-month picker. Click days to select; chevrons step months. Today is highlighted.
<Calendar
value={value}
onChange={setValue}
month={month}
onMonthChange={setMonth}
highlighted={TODAY}
/>value:Date | nullonChange:(date: Date) => voidmonth:DateonMonthChange:(date: Date) => voidhighlighted:DateDate Picker
Field + popover Calendar. Values are naive YYYY-MM-DD strings (the form-state shape). The popover flips above the field when there isn't room below.
<DatePicker value={date} onChange={setDate} />value:string | nullonChange:(value: string) => voidplaceholder:string= "Select a date"error:boolean= falsedisabled:boolean= falseTime Picker
Field + listbox of times at a fixed interval. Values are naive 24h HH:mm strings; labels display 12-hour. No Figma master yet — composed from the kit's field + listbox patterns.
<TimePicker value={time} onChange={setTime} step={15} />value:string | nullonChange:(value: string) => voidstep:number= 30placeholder:string= "Select a time"error:boolean= falsedisabled:boolean= falseData display
Surfaces that present tabular and list information.
Data Table
Toolbar + sortable, selectable table + pagination. Cells are ReactNode — Badge/Avatar/FontAwesomeIcon compose freely.
| Name | Assignee | Priority | Status | Updated | ||
|---|---|---|---|---|---|---|
| Lobby HVAC | AGAshley Green | Medium | Finalized | 2h ago | ||
| Warehouse door | OBOllie Brooks | High | In progress | 1d ago | ||
| Loading dock light | MGMitch Galehouse | Low | Pending | 3d ago |
| Name | Building | Updated | |
|---|---|---|---|
| Asset 1 | Building A | 1d ago | |
| Asset 2 | Building B | 2d ago | |
| Asset 3 | Building C | 3d ago | |
| Asset 4 | Building D | 4d ago | |
| Asset 5 | Building A | 5d ago | |
| Asset 6 | Building B | 6d ago | |
| Asset 7 | Building C | 7d ago | |
| Asset 8 | Building D | 8d ago | |
| Asset 9 | Building A | 9d ago | |
| Asset 10 | Building B | 10d ago | |
| Asset 11 | Building C | 11d ago | |
| Asset 12 | Building D | 12d ago | |
| Asset 13 | Building A | 13d ago | |
| Asset 14 | Building B | 14d ago | |
| Asset 15 | Building C | 15d ago | |
| Asset 16 | Building D | 16d ago | |
| Asset 17 | Building A | 17d ago | |
| Asset 18 | Building B | 18d ago | |
| Asset 19 | Building C | 19d ago | |
| Asset 20 | Building D | 20d ago | |
| Asset 21 | Building A | 21d ago | |
| Asset 22 | Building B | 22d ago | |
| Asset 23 | Building C | 23d ago | |
| Asset 24 | Building D | 24d ago | |
| Asset 25 | Building A | 25d ago |
<DataTable
selectable
columns={[{ key: "name", header: "Name", sortable: true }]}
rows={[{ id: "1", cells: { name: "Lobby" } }]}
/>columns:DataTableColumn[]rows:DataTableRow[]selectable:boolean= falserowActions:(rowId: string) => voidsortKey / sortDirection:string / "asc" | "desc"selectedIds / onSelectionChange:string[] / fnfooter / stickyFooter:ReactNode / boolean= — / falsefillHeight:boolean= falseItem / Item Set
List-row primitive (Item) grouped into a bordered card (ItemSet), with an optional section heading above it. Vertical and horizontal layouts.
<Item
label="Assignee"
text="Ashley Green"
leadingAvatar={{ initials: "AG" }}
trailing={<Badge type="soft">Active</Badge>}
/>orientation:"default" | "horizontal"= "default"label:ReactNodetext:ReactNodesupportingText:ReactNodeleadingIcon:IconDefinitionleadingAvatar:{ src?, alt?, initials? }trailing:ReactNodeonClick:() => void<ItemSet heading="Details">
<Item label="Status" text="Open" />
<Item label="Priority" text="High" />
</ItemSet>heading:ReactNodedescription:ReactNodeheadingAvatar:{ src?, alt?, initials? }children:ReactNodeTokens
The design-system primitives every component resolves to — values from kits/go/tokens/* mirrored to Tailwind @theme in app/globals.css.