UNPKG

goobs-frontend

Version:

A comprehensive React-based libary for building modern web applications

308 lines 15.2 kB
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