/** * A header button that parks an explanation behind one click. The AI * Visibility page used to open with full-width blocks of prose above the * report - the merchant scrolled past a screen of documentation before * reaching a single number. The copy is unchanged, it just waits to be asked * for. */ import React, { ReactNode, useState } from 'react'; import Modal from './Modal'; interface InfoDialogButtonProps { /** Short label on the trigger. */ label: string; /** Icon rendered before the label. */ icon: ReactNode; /** Heading inside the dialog. */ title: string; /** One line under the title, for context the body assumes. */ subtitle?: string; /** ``warning`` paints the trigger amber, matching the banner it replaced. */ tone?: 'default' | 'warning'; /** * Drop the label and render just the icon, so the header bar stays on a * single row; the label survives as the tooltip and accessible name. */ compact?: boolean; /** The explanation itself. */ children: ReactNode; } /** Trigger surface per tone, matching the header's other secondary buttons. */ const TONE_CLASSES: Record<'default' | 'warning', string> = { default: 'border-gray-300 bg-white text-gray-700 hover:bg-gray-50 hover:text-gray-900', warning: 'border-amber-300 bg-amber-50 text-amber-800 hover:bg-amber-100 hover:text-amber-900', }; /** * The trigger plus its dialog. * * @param {InfoDialogButtonProps} props - Label, icon, tone and body. * @returns {JSX.Element} Button and dialog. */ const InfoDialogButton = ({ label, icon, title, subtitle, tone = 'default', compact = false, children, }: InfoDialogButtonProps): JSX.Element => { const [open, setOpen] = useState(false); return ( <> setOpen(false)} title={title}> {subtitle &&

{subtitle}

}
{children}
); }; export default InfoDialogButton;