{"version":3,"sources":["../src/campaigns-carousel/types.ts","../src/campaigns-carousel/LegionCampaignsCarousel.tsx"],"names":["LegionCampaignsCarousel"],"mappings":"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","file":"campaigns-carousel.mjs","sourcesContent":["/**\n * Theming props for the Campaigns Carousel Widget.\n * Unlike other widgets, the carousel uses camelCase query parameters\n * rather than kebab-case CSS variable parameters.\n */\nexport interface CampaignsCarouselThemingProps {\n  /** Panel gradient start color, e.g. \"#1a1b5e\" */\n  panelStart?: string;\n  /** Panel gradient mid color */\n  panelMid?: string;\n  /** Panel gradient end color */\n  panelEnd?: string;\n  /** Panel box shadow */\n  panelShadow?: string;\n  /** Title font size, e.g. \"1.5rem\" */\n  titleSize?: string;\n  /** Description font size, e.g. \"0.9rem\" */\n  descriptionSize?: string;\n  /** Title text shadow */\n  titleShadow?: string;\n  /** Description text shadow */\n  descriptionShadow?: string;\n}\n\n/**\n * Core configuration props for the Campaigns Carousel Widget.\n */\nexport interface CampaignsCarouselWidgetProps\n  extends CampaignsCarouselThemingProps {\n  /** Base URL of the Legion application (required) */\n  baseUrl: string;\n  /** API key for authorization */\n  apiKey?: string;\n  /** Maximum number of campaigns to show (default: 5) */\n  maxCampaigns?: number;\n  /** Whether to show expiration dates (default: true) */\n  showExpiration?: boolean;\n  /** Theme preset. Default: \"light\" */\n  theme?: \"light\" | \"dark\";\n  /** Widget height in pixels. Default: 280 */\n  height?: number;\n  /** Widget width CSS value. Default: \"100%\" */\n  width?: string;\n  /** Additional CSS class name for the container */\n  className?: string;\n  /** Additional inline styles for the container */\n  style?: React.CSSProperties;\n  /** Callback when the widget iframe has loaded */\n  onLoad?: (detail: {\n    widget: string;\n    maxCampaigns: number;\n    theme: string;\n  }) => void;\n  /** Callback when the widget iframe fails to load */\n  onError?: (message: string) => void;\n}\n\n/**\n * Mapping from camelCase theming prop names to the camelCase query\n * parameter names used by the campaigns carousel widget iframe URL.\n *\n * NOTE: Unlike other widgets, this uses camelCase params (not kebab-case).\n */\nexport const CAROUSEL_THEMING_PROP_TO_PARAM: Record<\n  keyof CampaignsCarouselThemingProps,\n  string\n> = {\n  panelStart: \"panelStart\",\n  panelMid: \"panelMid\",\n  panelEnd: \"panelEnd\",\n  panelShadow: \"panelShadow\",\n  titleSize: \"titleSize\",\n  descriptionSize: \"descriptionSize\",\n  titleShadow: \"titleShadow\",\n  descriptionShadow: \"descriptionShadow\",\n};\n\n","import {\n  useRef,\n  useCallback,\n  useMemo,\n  forwardRef,\n  useImperativeHandle,\n} from \"react\";\nimport {\n  type CampaignsCarouselWidgetProps,\n  type CampaignsCarouselThemingProps,\n  CAROUSEL_THEMING_PROP_TO_PARAM,\n} from \"./types\";\n\n/**\n * Ref handle exposed by LegionCampaignsCarousel for imperative control.\n */\nexport interface LegionCampaignsCarouselHandle {\n  /** Reload the widget iframe */\n  refresh: () => void;\n}\n\n/**\n * Build the iframe src URL from widget props.\n */\nexport function buildCampaignsCarouselWidgetUrl(\n  props: CampaignsCarouselWidgetProps\n): string {\n  const {\n    baseUrl,\n    apiKey,\n    maxCampaigns = 5,\n    showExpiration = true,\n    theme = \"light\",\n    height = 280,\n  } = props;\n\n  const url = new URL(\"/widget/campaigns-carousel\", baseUrl);\n  url.searchParams.set(\"maxCampaigns\", String(maxCampaigns));\n  url.searchParams.set(\"showExpiration\", String(showExpiration));\n  url.searchParams.set(\"theme\", theme);\n  url.searchParams.set(\"height\", String(height));\n\n  if (apiKey) {\n    url.searchParams.set(\"apiKey\", apiKey);\n  }\n\n  // Append theming params (camelCase, not kebab-case)\n  const themingKeys = Object.keys(CAROUSEL_THEMING_PROP_TO_PARAM) as Array<\n    keyof CampaignsCarouselThemingProps\n  >;\n  for (const key of themingKeys) {\n    const value = props[key];\n    if (value !== undefined && value !== null && String(value).length > 0) {\n      url.searchParams.set(CAROUSEL_THEMING_PROP_TO_PARAM[key], String(value));\n    }\n  }\n\n  return url.toString();\n}\n\n/**\n * LegionCampaignsCarousel – a React component that embeds the Legion\n * Campaigns Carousel widget via an iframe.\n *\n * @example\n * ```tsx\n * import { LegionCampaignsCarousel } from '@legionhandtech/lht-react-widgets';\n *\n * function App() {\n *   return (\n *     <LegionCampaignsCarousel\n *       baseUrl=\"https://your-legion-domain.com\"\n *       apiKey=\"your-api-key\"\n *       maxCampaigns={5}\n *       theme=\"light\"\n *     />\n *   );\n * }\n * ```\n */\nexport const LegionCampaignsCarousel = forwardRef<\n  LegionCampaignsCarouselHandle,\n  CampaignsCarouselWidgetProps\n>(function LegionCampaignsCarousel(props, ref) {\n  const {\n    maxCampaigns = 5,\n    showExpiration = true,\n    theme = \"light\",\n    height = 280,\n    apiKey,\n    width = \"100%\",\n    className,\n    style,\n    onLoad,\n    onError,\n    baseUrl,\n    ...rest\n  } = props;\n\n  const iframeRef = useRef<HTMLIFrameElement>(null);\n\n  useImperativeHandle(\n    ref,\n    () => ({\n      refresh: () => {\n        const iframe = iframeRef.current;\n        if (iframe?.contentWindow) {\n          iframe.contentWindow.location.reload();\n        }\n      },\n    }),\n    []\n  );\n\n  const src = useMemo(\n    () => buildCampaignsCarouselWidgetUrl(props),\n    [\n      baseUrl,\n      apiKey,\n      maxCampaigns,\n      showExpiration,\n      theme,\n      height,\n      ...Object.keys(CAROUSEL_THEMING_PROP_TO_PARAM).map(\n        (k) => rest[k as keyof typeof rest]\n      ),\n    ]\n  );\n\n  const handleLoad = useCallback(() => {\n    onLoad?.({ widget: \"campaigns-carousel\", maxCampaigns, theme });\n  }, [maxCampaigns, theme, onLoad]);\n\n  const handleError = useCallback(() => {\n    onError?.(\"Failed to load campaigns carousel widget\");\n  }, [onError]);\n\n  const resolvedHeight = `${height}px`;\n\n  return (\n    <div\n      className={className}\n      style={{ width, height: resolvedHeight, ...style }}\n      data-testid=\"legion-campaigns-carousel\"\n    >\n      <iframe\n        ref={iframeRef}\n        src={src}\n        title=\"Campaigns Carousel Widget\"\n        width=\"100%\"\n        height=\"100%\"\n        frameBorder=\"0\"\n        scrolling=\"no\"\n        loading=\"lazy\"\n        onLoad={handleLoad}\n        onError={handleError}\n        style={{ border: \"none\" }}\n      />\n    </div>\n  );\n});\n\n"]}