import { ReactNode } from 'react'; import { LocalizedText, AudienceProp } from '@tour-kit/core'; import { MediaSlotType } from '@tour-kit/media'; import { E as EngineAnnouncementConfig, A as AnnouncementVariant, D as DismissalReason } from './types-MpBl5-ej.js'; /** * Public, JSON-serializable changelog entry used by `serializeFeed`. * * Extends `AnnouncementConfig` with publish-time metadata. Reuses the * announcement shape so a config that already drives an in-app modal can * simultaneously be syndicated as RSS/JSON Feed. */ interface ChangelogEntry extends AnnouncementConfig { /** * Stable publish timestamp. Accepts a `Date` or any `Date`-parseable string * (ISO 8601 recommended). Invalid values cause `serializeFeed` to throw a * `TypeError` rather than emitting `Invalid Date` into the feed. */ publishedAt: Date | string; /** * Absolute URL of the canonical changelog page for this entry. Used as * the RSS `` and the JSON Feed `url` field. */ permalink: string; /** * Optional category tag (e.g. `'feature'`, `'fix'`). Surfaces as `` * in RSS and `tags: [category]` in JSON Feed. */ category?: string; /** * Optional rendered HTML body. Emitted only as JSON Feed `content_html`; * RSS `` always uses the plain-string `description` field * (never raw HTML, to keep the entity-escape contract intact). */ contentHtml?: string; } /** * Publisher-level metadata applied once per feed. * * `feedUrl` is the base URL of the changelog feed routes; the serializer * appends `.xml` for the RSS self-link and `.json` for the JSON Feed * `feed_url`. Example: `'https://acme.com/changelog'` → routes * `https://acme.com/changelog.xml` and `https://acme.com/changelog.json`. */ interface SerializeFeedOptions { title: string; description: string; siteUrl: string; feedUrl: string; language?: string; copyright?: string; } /** * Pure, side-effect-free RSS 2.0 + JSON Feed 1.1 serializer. * * Throws `TypeError` when any entry has an invalid `publishedAt` — fail-fast * to avoid emitting `Invalid Date` strings into a live feed. */ declare function serializeFeed(entries: ChangelogEntry[], opts: SerializeFeedOptions): { rss: string; jsonFeed: string; }; /** * Action button configuration */ interface AnnouncementAction { label: string; onClick?: () => void; href?: string; variant?: 'primary' | 'secondary' | 'ghost' | 'link'; /** If true, clicking this action dismisses the announcement */ dismissOnClick?: boolean; } /** * Media configuration for announcements. * * Phase 4 widening: `type` was previously `'image' | 'video' | 'lottie'`. It is * now the full `MediaSlotType` union (9 values incl. `'auto'`) so consumers can * point at YouTube/Vimeo/Loom/Wistia/GIF URLs and have `` dispatch * automatically. The narrower legacy values stay assignable — non-breaking. */ interface AnnouncementMedia { type?: MediaSlotType; src: string; alt?: string; poster?: string; aspectRatio?: string; autoplay?: boolean; loop?: boolean; muted?: boolean; } /** * Position options for different variants */ type BannerPosition = 'top' | 'bottom'; type SlideoutPosition = 'left' | 'right'; type ToastPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'top-center' | 'bottom-center'; /** * Variant-specific options */ interface ModalOptions { size?: 'sm' | 'md' | 'lg' | 'xl' | 'full'; closeOnOverlayClick?: boolean; closeOnEscape?: boolean; showCloseButton?: boolean; } interface SlideoutOptions { position?: SlideoutPosition; size?: 'sm' | 'md' | 'lg'; closeOnOverlayClick?: boolean; closeOnEscape?: boolean; showCloseButton?: boolean; } interface BannerOptions { position?: BannerPosition; sticky?: boolean; dismissable?: boolean; intent?: 'info' | 'success' | 'warning' | 'error'; } interface ToastOptions { position?: ToastPosition; autoDismiss?: boolean; autoDismissDelay?: number; showProgress?: boolean; intent?: 'info' | 'success' | 'warning' | 'error'; } interface SpotlightOptions { targetSelector: string; placement?: 'top' | 'right' | 'bottom' | 'left'; offset?: number; showOverlay?: boolean; overlayOpacity?: number; closeOnOverlayClick?: boolean; } /** * Main announcement configuration */ interface AnnouncementConfig extends EngineAnnouncementConfig { /** Unique identifier for the announcement */ id: string; /** * Display variant. Required here, optional on `EngineAnnouncementConfig` — * an engine-only consumer renders its own UI and has no variant to pick. */ variant: AnnouncementVariant; /** * Title of the announcement. Supports plain strings (interpolated against * `userContext` from ``), i18n keys * (`{ key: 'announcement.foo.title' }` resolved via `useT()`), or any * `ReactNode` body. Strings without `{{var}}` tokens render unchanged. */ title?: ReactNode | LocalizedText; /** * Description or body content. Same `ReactNode | LocalizedText` shape as * `title`; ReactNode children pass through unchanged so consumers can * supply rich JSX bodies. */ description?: ReactNode | LocalizedText; /** Media to display */ media?: AnnouncementMedia; /** Primary action button */ primaryAction?: AnnouncementAction; /** Secondary action button */ secondaryAction?: AnnouncementAction; /** * Audience targeting. Accepts either an inline `AudienceCondition[]` (legacy) * evaluated by `matchesAudience(...)`, or a `{ segment: string }` reference * to a segment registered in `` and evaluated by * `useSegments()`. The array branch is fully backward-compatible. */ audience?: AudienceProp; /** Variant-specific options */ modalOptions?: ModalOptions; slideoutOptions?: SlideoutOptions; bannerOptions?: BannerOptions; toastOptions?: ToastOptions; spotlightOptions?: SpotlightOptions; /** * Optional free-form category tag — presentation-layer metadata only. * Phase 5a's changelog feed will read this for grouping and filtering; * 3c only round-trips the field through the type system. Examples: * `'feature'`, `'fix'`, `'breaking'`, `'security'`. */ category?: string; /** Custom metadata */ metadata?: Record; /** * Show this announcement automatically on mount or when eligibility changes. * Default: `true`. Set to `false` to trigger imperatively via `show(id)`. */ autoShow?: boolean; /** Callback when announcement is shown */ onShow?: () => void; /** Callback when announcement is dismissed */ onDismiss?: (reason: DismissalReason) => void; /** Callback when primary action is completed */ onComplete?: () => void; } export { type AnnouncementMedia as A, type BannerOptions as B, type ChangelogEntry as C, type ModalOptions as M, type SlideoutOptions as S, type ToastOptions as T, type AnnouncementAction as a, type SpotlightOptions as b, type AnnouncementConfig as c, type BannerPosition as d, type SerializeFeedOptions as e, type SlideoutPosition as f, type ToastPosition as g, serializeFeed as s };