import { type HTMLAttributes, type ReactNode } from 'react'; import { type VariantProps } from 'class-variance-authority'; /** * One product-hub release entry. The kit is purely presentational — * the consumer fetches releases (Supabase, REST, …) and maps them into * this shape. */ export interface ProductHubItem { /** Unique identifier for the release. */ id: string; /** Release title — rendered bold on the first line. */ title: string; /** Short release summary — rendered as plain text, clamped to 2 lines. */ summary?: string; /** ISO-8601 publish date — rendered as a localised, italic absolute date. */ dateIso?: string; /** * Thumbnail URL. Guarded through the shared `safeImageSrc` allow-list * and rendered with `referrerPolicy="no-referrer"`. Unsafe or missing * sources fall back to a Gift glyph tile. */ imageUrl?: string; /** * Release deep link. Guarded through `isSafeEntityUrl`; safe URLs make * the row title an anchor that opens in a new tab. Unsafe URLs render * the title as plain text. */ url?: string; /** Marks the release as not yet seen — highlights the row and counts toward the trigger badge. */ unseen?: boolean; } /** * Curated imperative handle for ProductHubTray. Exposed to the agent * registry so a future MCP UI bridge can drive the tray without touching * the DOM. See `product-hub-tray.agent.ts`. */ export interface ProductHubTrayHandle { open: () => void; close: () => void; getUnseenCount: () => number; } export interface ProductHubTrayProps extends Omit, 'onClick' | 'children' | 'role' | 'id'>, VariantProps { /** * Stable instance id. Surfaced on the root as `data-component-id` so * an agent / MCP UI bridge can address this specific tray. */ id?: string; /** Releases rendered in the dropdown panel, newest first. */ items: ProductHubItem[]; /** * Product-hub landing URL. When set (and safe) the panel renders a * pinned "Open in Product Hub" footer link that opens in a new tab. */ hubUrl?: string; /** When true the panel shows skeleton placeholders. */ loading?: boolean; /** Error-state slot — rendered inside the panel instead of the list. */ error?: ReactNode; /** * Unseen-release count override. Defaults to the number of `items` * with `unseen: true`. Drives the trigger badge. */ unseenCount?: number; /** Fires when the open state changes. */ onOpenChange?: (open: boolean) => void; /** * Analytics hook — fires when a row is activated. Navigation itself is * owned by the row anchor (new tab); this callback must not be relied * on for routing. */ onItemActivate?: (item: ProductHubItem) => void; /** Override for the trigger's accessible label. */ triggerLabel?: string; /** Number of releases rendered before the rest are cut off. Default 10. */ maxVisible?: number; /** Empty-state slot — replaces the built-in "No product updates yet" panel. */ emptyState?: ReactNode; /** Open the panel on first mount (uncontrolled). */ defaultOpen?: boolean; /** BCP-47 locale override for the per-row dates. Falls back to `i18n.language`. */ locale?: string; /** Panel alignment relative to the trigger. Default `'end'`. */ align?: 'start' | 'center' | 'end'; /** Side of the trigger to open on. Default `'bottom'`. */ side?: 'top' | 'bottom'; } declare const productHubTrayVariants: (props?: ({ size?: "sm" | "md" | null | undefined; } & import("class-variance-authority/types").ClassProp) | undefined) => string; export interface ProductHubUpdateRowProps extends Omit, 'onClick' | 'role' | 'title'> { /** The release to render. */ item: ProductHubItem; /** `tray` — compact dropdown row. `panel` — roomier dashboard row. */ density?: 'tray' | 'panel'; /** * Row chrome. `'flat'` (default) — chrome-less row inside a bordered * tray/panel. `'elevated'` — own card chrome (border + `--shadow-sm`) for * rail feeds (e.g. the Inbox), matching the sibling notification/message * cards. */ surface?: 'flat' | 'elevated'; /** BCP-47 locale override for the date. */ locale?: string; /** Analytics hook — navigation is owned by the row anchor. */ onActivate?: (item: ProductHubItem) => void; /** * When supplied, renders a close affordance (revealed on row hover / focus) * that fires with this item — e.g. dismissing the update from an Inbox feed. */ onDismiss?: (item: ProductHubItem) => void; } /** * @internal Shared row between ProductHubTray and ProductHubPanel. * Exported for the sibling panel only — import the trays, not this. */ export declare function ProductHubUpdateRow({ item, density, surface, locale, onActivate, onDismiss, className, ...rest }: ProductHubUpdateRowProps): import("react/jsx-runtime").JSX.Element; /** @internal Skeleton placeholder mirroring the row layout. */ export declare function UpdateSkeletonRow({ density, }: { density?: 'tray' | 'panel'; }): import("react/jsx-runtime").JSX.Element; /** @internal Centered status container for error / consumer-slot states. */ export declare function UpdateStatusPanel({ children }: { children: ReactNode; }): import("react/jsx-runtime").JSX.Element; export declare const ProductHubTray: import("react").ForwardRefExoticComponent>; export {}; //# sourceMappingURL=product-hub-tray.d.ts.map