Server Components
Available via @stackmates/ui-server-components
MetricCard
KPI card with value, label, optional variant coloring and trend indicator.
Total Contacts
Active Deals
Overdue Tasks
Pipeline Value
Conversion Rate %
Browse All Contacts
MetricCardProps
| Prop | Type | Default | Description |
|---|---|---|---|
| value* | string | number | — | Primary display value |
| label* | string | — | Label below the value |
| variant | 'default' | 'success' | 'danger' | 'warning' | 'info' | 'default' | Color variant for the value |
| trend | { change?: number; label?: string; direction?: "up" | "down" } | — | Optional trend indicator with change percentage or label |
| href | string | — | Makes the entire card a clickable link |
Installation
import { MetricCard } from '@stackmates/ui-server-components';Usage
Basic
<MetricCard value={142} label="Total Contacts" />With trend
<MetricCard value={38} label="Active Deals" variant="success" trend={{ change: 12.5 }} />Accessibility
- Value and label are visible text
- Trend icon is decorative
PageHeader
Page title with optional description and action slot.
Contacts
Manage your organization's contacts and relationships.
Dashboard
PageHeaderProps
| Prop | Type | Default | Description |
|---|---|---|---|
| title* | string | — | Page title text |
| description | string | — | Subtitle text below the title |
| children | ReactNode | — | Action slot (buttons, links) rendered on the right |
Installation
import { PageHeader } from '@stackmates/ui-server-components';Accessibility
- Title renders as <h1>
- Description provides context for screen readers
Card
Compound card with header, title, description, content, and footer slots.
3 active tasks, 2 pending review.
CardProps
| Prop | Type | Default | Description |
|---|---|---|---|
| children* | ReactNode | — | Card content — compose with CardHeader, CardContent, CardFooter |
| className | string | — | Additional CSS classes |
Installation
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@stackmates/ui-server-components';Accessibility
- Renders as semantic <div>
- CardTitle should match heading hierarchy
EmptyState
Empty state with title, description, variant illustration, and action slot.
No Contacts Yet
Add your first contact to start building relationships.
No Deals Found
Create a deal to track your sales pipeline.
EmptyStateProps
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | 'contacts' | 'deals' | 'default' | 'default' | Illustration variant |
| title* | string | — | Empty state heading |
| description* | string | — | Explanation text |
| actions | ReactNode | — | CTA button or link slot |
Installation
import { EmptyState } from '@stackmates/ui-server-components';Accessibility
- CTA should be a <button> or <a>
- Illustration is decorative
AccessDenied
403-style inline access denied. Renders in-place, not a redirect.
Access Denied
You don't have permission to access this feature. Contact your organisation admin to request access.
Go to HomeAccessDeniedProps
| Prop | Type | Default | Description |
|---|---|---|---|
| feature | string | — | Feature name shown in the denial message |
Installation
import { AccessDenied } from '@stackmates/ui-server-components';Accessibility
- Uses role="alert" to announce denial
PaginationControls
URL-based pagination using Next.js Link. Handles ellipsis for large ranges.
PaginationControlsProps
| Prop | Type | Default | Description |
|---|---|---|---|
| currentPage* | number | — | Active page number (1-based) |
| totalPages* | number | — | Total number of pages |
| basePath* | string | — | URL path to append ?page=N to |
Installation
import { PaginationControls } from '@stackmates/ui-server-components';Accessibility
- Uses <nav> with aria-label="Pagination"
- Current page via aria-current="page"
PaginationSummary
Text summary line for pagination context.
PaginationSummaryProps
| Prop | Type | Default | Description |
|---|---|---|---|
| text* | string | — | Summary text (e.g. "Showing 1-25 of 142") |
Installation
import { PaginationSummary } from '@stackmates/ui-server-components';Accessibility
- Renders as <p> with aria-live="polite"
AlertRx
Alert banner with title and description. Supports default and destructive variants.
AlertRxProps
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | 'default' | 'destructive' | 'default' | Alert style variant |
| children* | ReactNode | — | Alert content — compose with AlertRxTitle, AlertRxDescription |
Installation
import { AlertRx, AlertRxTitle, AlertRxDescription } from '@stackmates/ui-server-components';Accessibility
- Uses role="alert" for screen reader announcement
Heading / Subheading
Semantic heading and subheading components with consistent typography.
Heading level 1
Heading level 2
Subheading level 2
Subheading level 3
HeadingProps
| Prop | Type | Default | Description |
|---|---|---|---|
| level* | 1 | 2 | 3 | 4 | 5 | 6 | — | HTML heading level (h1-h6) |
| children* | ReactNode | — | Heading text content |
Installation
import { Heading, Subheading } from '@stackmates/ui-server-components';Accessibility
- Renders semantic <h1>-<h6> — maintain hierarchy
Text / TextLink / Strong / Code
Inline typography primitives for body text, links, emphasis, and code.
Standard text paragraph rendered on the server.
With TextLink, Strong, and Code inline.
Installation
import { Text, TextLink, Strong, Code } from '@stackmates/ui-server-components';Accessibility
- TextLink renders as <a>
- Strong renders as <strong>
ErrorMessage
Inline form error message with destructive styling.
This field is required.
Email address is not valid.
ErrorMessageProps
| Prop | Type | Default | Description |
|---|---|---|---|
| message* | string | — | Error message text to display |
Installation
import { ErrorMessage } from '@stackmates/ui-server-components';Accessibility
- Uses role="alert"
- Pair with aria-describedby on the related input
Skeleton
Loading placeholder with pulse animation. Shape via className.
SkeletonProps
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | — | Width, height, and border-radius via Tailwind classes |
Installation
import { Skeleton } from '@stackmates/ui-server-components';Accessibility
- Use aria-busy="true" on the container while loading
Link
Next.js Link wrapper for internal navigation.
Installation
import { Link } from '@stackmates/ui-server-components';Accessibility
- Renders as <a> — keyboard accessible
- Link text should describe destination