// ============================================================================ // Chatbot Main - Messages - Sources Card // ============================================================================ import type { FunctionComponent, MouseEvent as ReactMouseEvent, KeyboardEvent as ReactKeyboardEvent } from 'react'; import { useState } from 'react'; // Import PatternFly components import { Button, ButtonProps, ButtonVariant, Card, CardBody, CardBodyProps, CardFooter, CardFooterProps, CardProps, CardTitle, CardTitleProps, ExpandableSection, ExpandableSectionVariant, Icon, Truncate, TruncateProps } from '@patternfly/react-core'; import { ExternalLinkSquareAltIcon } from '@patternfly/react-icons'; export interface SourcesCardBaseProps extends CardProps { /** Additional classes for the pagination navigation container. */ className?: string; /** Flag indicating if the pagination is disabled. */ isDisabled?: boolean; /** @deprecated ofWord has been deprecated. Label for the English word "of." */ ofWord?: string; /** Accessible label for the pagination component. */ paginationAriaLabel?: string; /** Content rendered inside the paginated card */ sources: { /** Title of sources card */ title?: string; /** Subtitle of sources card */ subtitle?: string; /** Link to source */ link: string; /** Body of sources card */ body?: React.ReactNode | string; /** Whether link is external */ isExternal?: boolean; /** Whether sources card is expandable */ hasShowMore?: boolean; /** onClick event applied to the title of the Sources card */ onClick?: React.MouseEventHandler; /** Any additional props applied to the title of the Sources card */ titleProps?: ButtonProps; /** Custom footer applied to the Sources card */ footer?: React.ReactNode; /** Additional props passed to Truncate component */ truncateProps?: TruncateProps; }[]; /** Accessible label for the button which moves to the next page. */ toNextPageAriaLabel?: string; /** Accessible label for the button which moves to the previous page. */ toPreviousPageAriaLabel?: string; /** Function called when user clicks to navigate to next page. */ onNextClick?: (event: React.SyntheticEvent, page: number) => void; /** Function called when user clicks to navigate to previous page. */ onPreviousClick?: (event: React.SyntheticEvent, page: number) => void; /** Function called when page is changed. */ onSetPage?: (event: React.MouseEvent | React.KeyboardEvent | MouseEvent, newPage: number) => void; /** Label for English words "show more" */ showMoreWords?: string; /** Label for English words "show less" */ showLessWords?: string; /** Additional props passed to card title */ cardTitleProps?: CardTitleProps; /** Additional props passed to card body */ cardBodyProps?: CardBodyProps; /** Additional props passed to card footer */ cardFooterProps?: CardFooterProps; } const SourcesCardBase: FunctionComponent = ({ className, isDisabled, paginationAriaLabel = 'Pagination', sources, toNextPageAriaLabel = 'Go to next page', toPreviousPageAriaLabel = 'Go to previous page', onNextClick, onPreviousClick, onSetPage, showMoreWords = 'show more', showLessWords = 'show less', isCompact, cardTitleProps, cardBodyProps, cardFooterProps, ...props }: SourcesCardBaseProps) => { const [page, setPage] = useState(1); const [isExpanded, setIsExpanded] = useState(false); const onToggle = (_event: ReactMouseEvent, isExpanded: boolean) => { setIsExpanded(isExpanded); }; const handleNewPage = (_evt: ReactMouseEvent | ReactKeyboardEvent | MouseEvent, newPage: number) => { setPage(newPage); onSetPage && onSetPage(_evt, newPage); }; const renderTitle = (title?: string, truncateProps?: TruncateProps) => { if (title) { return ; } return `Source ${page}`; }; return (
{sources[page - 1].subtitle && ( {sources[page - 1].subtitle} )}
{sources[page - 1].body && ( {sources[page - 1].hasShowMore ? ( // prevents extra VO announcements of button text - parent Message has aria-live
{sources[page - 1].body}
) : (
{sources[page - 1].body}
)}
)} {sources[page - 1].footer ? ( {sources[page - 1].footer} ) : ( sources.length > 1 && (
) )}
); }; export default SourcesCardBase;