goobs-frontend
Version:
A comprehensive React-based libary for building modern web applications
308 lines • 15.2 kB
TypeScript
import { default as React, ReactElement, ReactNode } from 'react';
import { EmptyStateProps } from '../EmptyState';
export type CardTheme = 'sacred' | 'light' | 'dark';
export interface CardProps extends Omit<React.HTMLAttributes<HTMLElement>, 'title'> {
/** Visual density / padding scale. Default `'standard'`. */
variant?: 'standard' | 'compact';
/** Selection state — emits `data-card-state="selected"` + ring. */
selected?: boolean;
/**
* Marks the card as a click-target as a whole. Sets `cursor: pointer`
* and `data-card-interactive`. Click handling itself happens on
* `<Card.Title>` via its `onClick`/`href` (block-link pattern); this
* prop only signals the visual cue.
*/
interactive?: boolean;
/** Disabled visual state — drops opacity, blocks pointer events. */
disabled?: boolean;
/** Drag state — emits `data-card-state="dragging"`. */
dragging?: boolean;
/**
* Optional border-accent color. `side: 'left'` draws a thick left
* border in the color (the common "status-bar on left edge" pattern).
* `side: 'full'` replaces the full border color.
*/
borderAccent?: {
color: string;
side?: 'left' | 'full';
};
/** Test selector — emitted as `data-card-type` (e.g. `"statement"`). */
cardType?: string;
/** Test selector — emitted as `data-card-id`. */
cardId?: string;
/** Theming. Default `'sacred'`. */
styles?: {
theme?: CardTheme;
};
/**
* Polymorphic rendering — when true, forwards props to the single
* child element instead of wrapping. Same contract as Radix's `asChild`.
*/
asChild?: boolean;
children: ReactNode;
}
interface CardComponent {
(props: CardProps & React.RefAttributes<HTMLElement>): ReactElement | null;
displayName?: string;
Header: typeof CardHeader;
HeaderIcon: typeof CardHeaderIcon;
HeaderMeta: typeof CardHeaderMeta;
Title: typeof CardTitle;
Subtitle: typeof CardSubtitle;
HeaderBadges: typeof CardHeaderBadges;
HeaderActions: typeof CardHeaderActions;
SelectionCheckbox: typeof CardSelectionCheckbox;
Body: typeof CardBody;
Description: typeof CardDescription;
Section: typeof CardSection;
Banner: typeof CardBanner;
Metrics: typeof CardMetrics;
Metric: typeof CardMetric;
BigValue: typeof CardBigValue;
Stats: typeof CardStats;
StatCell: typeof CardStatCell;
Progress: typeof CardProgress;
Footer: typeof CardFooter;
FooterActions: typeof CardFooterActions;
FooterMeta: typeof CardFooterMeta;
ConfirmDelete: typeof CardConfirmDelete;
DragHandle: typeof CardDragHandle;
Grid: typeof CardGrid;
EmptyState: typeof CardEmptyState;
}
export interface CardHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
children: ReactNode;
}
declare const CardHeader: React.ForwardRefExoticComponent<CardHeaderProps & React.RefAttributes<HTMLDivElement>>;
export interface CardHeaderIconProps extends React.HTMLAttributes<HTMLSpanElement> {
children: ReactNode;
}
declare const CardHeaderIcon: React.ForwardRefExoticComponent<CardHeaderIconProps & React.RefAttributes<HTMLSpanElement>>;
type HeadingLevel = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
export interface CardTitleProps extends Omit<React.HTMLAttributes<HTMLHeadingElement>, 'onClick'> {
children: ReactNode;
/** Heading level. Default `'h3'`. */
as?: HeadingLevel;
/** When set, the title text becomes an `<a>` and the link's `::after`
* overlay extends the click target across the whole card. */
href?: string;
/** When set, the title text becomes a `<button>` and the button's
* `::after` overlay extends the click target across the whole card.
* Mutually exclusive with `href` (href wins). */
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
/** Optional aria-label for the link/button (defaults to text content). */
ariaLabel?: string;
/** Polymorphic — forwards props to the single child instead of wrapping. */
asChild?: boolean;
}
declare function CardTitle({ as, href, onClick, ariaLabel, asChild, className, children, ref, ...restProps }: CardTitleProps & React.RefAttributes<HTMLElement>): ReactElement | null;
declare namespace CardTitle {
var displayName: string;
}
export interface CardSubtitleProps extends React.HTMLAttributes<HTMLSpanElement> {
children: ReactNode;
}
declare const CardSubtitle: React.ForwardRefExoticComponent<CardSubtitleProps & React.RefAttributes<HTMLSpanElement>>;
export interface CardHeaderBadgesProps extends React.HTMLAttributes<HTMLDivElement> {
children: ReactNode;
}
declare const CardHeaderBadges: React.ForwardRefExoticComponent<CardHeaderBadgesProps & React.RefAttributes<HTMLDivElement>>;
export interface CardHeaderActionsProps extends React.HTMLAttributes<HTMLDivElement> {
children: ReactNode;
}
declare const CardHeaderActions: React.ForwardRefExoticComponent<CardHeaderActionsProps & React.RefAttributes<HTMLDivElement>>;
export interface CardSelectionCheckboxProps {
checked: boolean;
/**
* Selection-change handler. Receives both the new boolean state AND
* the native ChangeEvent so callers wrapping the card in an outer
* click handler can `event.stopPropagation()` to keep clicks scoped
* to the checkbox.
*/
onChange: (next: boolean, event: React.ChangeEvent<HTMLInputElement>) => void;
/** Accessible label (e.g. "Select this contract"). */
ariaLabel: string;
disabled?: boolean;
}
declare const CardSelectionCheckbox: React.ForwardRefExoticComponent<CardSelectionCheckboxProps & React.RefAttributes<HTMLInputElement>>;
export interface CardBodyProps extends React.HTMLAttributes<HTMLDivElement> {
children: ReactNode;
}
declare const CardBody: React.ForwardRefExoticComponent<CardBodyProps & React.RefAttributes<HTMLDivElement>>;
export interface CardDescriptionProps extends React.HTMLAttributes<HTMLParagraphElement> {
children: ReactNode;
}
declare const CardDescription: React.ForwardRefExoticComponent<CardDescriptionProps & React.RefAttributes<HTMLParagraphElement>>;
export interface CardMetricsProps extends React.HTMLAttributes<HTMLDivElement> {
children: ReactNode;
}
declare const CardMetrics: React.ForwardRefExoticComponent<CardMetricsProps & React.RefAttributes<HTMLDivElement>>;
export interface CardMetricProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'children'> {
/** Optional icon glyph or SVG node. */
icon?: ReactNode;
/** Small uppercase-ish label rendered before the value. */
label?: ReactNode;
/** Primary numeric / text value. */
value: ReactNode;
/** Accent color (left border + value text). */
color?: string;
/** Render the value in a monospace font (for IP / CIDR / MAC / OID
* values that callsites previously wrapped in `<code>` literals). */
mono?: boolean;
}
declare const CardMetric: React.ForwardRefExoticComponent<CardMetricProps & React.RefAttributes<HTMLSpanElement>>;
export interface CardStatsProps extends React.HTMLAttributes<HTMLDivElement> {
/** Number of columns (default 2). */
columns?: number;
children: ReactNode;
}
declare const CardStats: React.ForwardRefExoticComponent<CardStatsProps & React.RefAttributes<HTMLDivElement>>;
export interface CardStatCellProps {
label: ReactNode;
value: ReactNode;
/** Optional accent for the value (e.g. red for overdue, green for paid). */
valueColor?: string;
/** Render the value in a monospace font (CIDR, IP, MAC, OID, etc.). */
mono?: boolean;
/** Optional secondary line under the value (e.g. "3 items"). */
caption?: ReactNode;
}
declare const CardStatCell: React.ForwardRefExoticComponent<CardStatCellProps & React.RefAttributes<HTMLDivElement>>;
export interface CardProgressProps {
/** Progress fraction, 0-1. */
value: number;
/** Optional label rendered above the bar. */
label?: ReactNode;
/** Optional override for the fill color. Defaults to theme accent. */
color?: string;
/** Override displayed percentage (default `${Math.round(value * 100)}%`). */
displayValue?: string;
}
declare const CardProgress: React.ForwardRefExoticComponent<CardProgressProps & React.RefAttributes<HTMLDivElement>>;
export interface CardFooterProps extends React.HTMLAttributes<HTMLDivElement> {
/** When true, left and right action groups are separated by margin-right:auto
* so the first child is left-aligned and the second is right-aligned. */
split?: boolean;
children: ReactNode;
}
declare const CardFooter: React.ForwardRefExoticComponent<CardFooterProps & React.RefAttributes<HTMLDivElement>>;
export interface CardFooterActionsProps extends React.HTMLAttributes<HTMLDivElement> {
side?: 'left' | 'right';
children: ReactNode;
}
declare const CardFooterActions: React.ForwardRefExoticComponent<CardFooterActionsProps & React.RefAttributes<HTMLDivElement>>;
export interface CardFooterMetaProps extends React.HTMLAttributes<HTMLSpanElement> {
children: ReactNode;
}
declare const CardFooterMeta: React.ForwardRefExoticComponent<CardFooterMetaProps & React.RefAttributes<HTMLSpanElement>>;
export interface CardSectionProps extends React.HTMLAttributes<HTMLDivElement> {
/** Optional uppercase eyebrow label (e.g. "Network Hierarchy"). */
label?: ReactNode;
/** Use the muted (grey) palette instead of the accent-tinted background. */
muted?: boolean;
children: ReactNode;
}
declare const CardSection: React.ForwardRefExoticComponent<CardSectionProps & React.RefAttributes<HTMLDivElement>>;
export type CardBannerTone = 'info' | 'success' | 'warn' | 'danger' | 'neutral';
export interface CardBannerProps {
/** Severity palette — drives background, border, text color. */
tone?: CardBannerTone;
/** Optional leading icon / emoji. */
icon?: ReactNode;
/** Optional bold title rendered above the message. */
title?: ReactNode;
/** Message body (always rendered when children/message provided). */
message?: ReactNode;
/** Custom children rendered after title+message. Lets callers embed
* links / buttons inline within the banner. */
children?: ReactNode;
}
declare const CardBanner: React.ForwardRefExoticComponent<CardBannerProps & React.RefAttributes<HTMLDivElement>>;
export interface CardHeaderMetaProps extends React.HTMLAttributes<HTMLSpanElement> {
children: ReactNode;
}
declare const CardHeaderMeta: React.ForwardRefExoticComponent<CardHeaderMetaProps & React.RefAttributes<HTMLSpanElement>>;
export type CardBigValueTone = 'success' | 'warn' | 'danger' | 'info' | 'neutral' | 'gold';
export interface CardBigValueProps {
/** Small uppercase label rendered above the value. */
label: ReactNode;
/** Primary numeric / short text (rendered 1.4–1.6rem, 700 weight). */
value: ReactNode;
/** Optional secondary line under the value (e.g. "12% vs last month"). */
caption?: ReactNode;
/** Optional accent color rendered as a small dot next to the label. */
swatch?: string;
/** Tone driving the value's color. Defaults to theme accent. */
tone?: CardBigValueTone;
}
declare const CardBigValue: React.ForwardRefExoticComponent<CardBigValueProps & React.RefAttributes<HTMLDivElement>>;
export interface CardConfirmDeleteProps {
/** Pre-formatted confirmation question (e.g. `Delete "Acme Inc"?`). */
message: ReactNode;
/** Confirm handler — usually calls the parent `onDelete(id)`. */
onConfirm: () => void;
/** Cancel handler — usually flips `showConfirm` back to false. */
onCancel: () => void;
/** Label for the confirm button. Default `'Yes, Delete'`. */
confirmLabel?: string;
/** Label for the cancel button. Default `'Cancel'`. */
cancelLabel?: string;
/**
* Optional renderer for the action buttons. When supplied, receives
* `{ onConfirm, onCancel }` and is responsible for the two buttons —
* lets callers swap in their own goobs `<CustomButton>` styling
* without the Card primitive having to import CustomButton itself
* (avoids a Card→Button dependency cycle).
*
* When omitted, renders plain `<button>` elements styled by the CSS
* module. Most callsites should pass `renderActions` so the buttons
* match the rest of the workspace's button design.
*/
renderActions?: (slot: {
onConfirm: () => void;
onCancel: () => void;
confirmLabel: string;
cancelLabel: string;
}) => ReactNode;
}
declare const CardConfirmDelete: React.ForwardRefExoticComponent<CardConfirmDeleteProps & React.RefAttributes<HTMLDivElement>>;
export interface CardDragHandleProps {
/** Accessible label for the handle (e.g. "Reorder step 3"). */
ariaLabel: string;
/** Move-up handler. When omitted, the up button is disabled. */
onMoveUp?: () => void;
/** Move-down handler. When omitted, the down button is disabled. */
onMoveDown?: () => void;
/** Visual grip glyph. Default `'⋮⋮'`. */
grip?: ReactNode;
}
declare const CardDragHandle: React.ForwardRefExoticComponent<CardDragHandleProps & React.RefAttributes<HTMLDivElement>>;
export interface CardGridProps extends Omit<React.HTMLAttributes<HTMLUListElement>, 'children'> {
/** Minimum column width passed to `repeat(auto-fill, minmax(...))`. */
minWidth?: string;
/** CSS gap between cards. */
gap?: string;
/** Auto-rendered when `children` is empty. */
empty?: ReactNode;
children: ReactNode;
}
declare const CardGrid: React.ForwardRefExoticComponent<CardGridProps & React.RefAttributes<HTMLUListElement>>;
export type CardEmptyStateProps = EmptyStateProps;
declare const CardEmptyState: React.ForwardRefExoticComponent<EmptyStateProps & React.RefAttributes<HTMLDivElement>>;
/**
* Compound-component card root: renders an `<article role="article">` labelled
* (via `aria-labelledby`) by the id of its `<Card.Title>`, with every card
* region composed from the static subcomponents (`Card.Header`, `Card.Body`,
* `Card.Footer`, `Card.Metrics`, `Card.Grid`, …). Click handling follows the
* block-link pattern — `<Card.Title href|onClick>` gets a `::after` overlay
* that stretches the click target across the whole card while inner
* interactive elements stay individually clickable. `Card` and `Card.Title`
* accept `asChild` (Radix slot pattern) to forward their props onto a single
* child element instead of wrapping it. Theming via `styles.theme` (default
* `'sacred'`), emitted as `data-theme`; state, selection, and type surface as
* `data-card-*` attributes for tests.
*/
declare const Card: CardComponent;
export { CardHeader, CardHeaderIcon, CardHeaderMeta, CardTitle, CardSubtitle, CardHeaderBadges, CardHeaderActions, CardSelectionCheckbox, CardBody, CardDescription, CardSection, CardBanner, CardMetrics, CardMetric, CardBigValue, CardStats, CardStatCell, CardProgress, CardFooter, CardFooterActions, CardFooterMeta, CardConfirmDelete, CardDragHandle, CardGrid, CardEmptyState, };
export default Card;
//# sourceMappingURL=index.d.ts.map