import * as React from 'react'; import { useState } from 'react'; import { css } from '@patternfly/react-styles'; import styles from '@patternfly/react-styles/css/components/Alert/alert'; import { AlertIcon } from './AlertIcon'; import { capitalize, useOUIAProps, OUIAProps } from '../../helpers'; import { AlertContext } from './AlertContext'; import maxLines from '@patternfly/react-tokens/dist/esm/c_alert__title_max_lines'; import { Tooltip, TooltipPosition } from '../Tooltip'; import { AlertToggleExpandButton } from './AlertToggleExpandButton'; export enum AlertVariant { success = 'success', danger = 'danger', warning = 'warning', info = 'info', custom = 'custom' } /** The main alert component. */ export interface AlertProps extends Omit, 'action' | 'title'>, OUIAProps { /** Close button; use the alert action close button component. */ actionClose?: React.ReactNode; /** Action links; use a single alert action link component or multiple wrapped in an array * or React.Fragment. */ actionLinks?: React.ReactNode; /** Content rendered inside the alert. */ children?: React.ReactNode; /** Additional classes to add to the alert. */ className?: string; /** Set a custom icon to the alert. If not set the icon is set according to the variant. */ customIcon?: React.ReactNode; /** Uniquely identifies the alert. */ id?: string; /** Flag indicating that the alert is expandable. */ isExpandable?: boolean; /** Flag to indicate if the alert is inline. */ isInline?: boolean; /** Flag to indicate if the alert is in a live region. */ isLiveRegion?: boolean; /** Flag to indicate if the alert is plain. */ isPlain?: boolean; /** Function to be executed on alert timeout. Relevant when the timeout prop is set. */ onTimeout?: () => void; /** If set to true, the timeout is 8000 milliseconds. If a number is provided, alert will * be dismissed after that amount of time in milliseconds. */ timeout?: number | boolean; /** If the user hovers over the alert and `timeout` expires, this is how long to wait * before finally dismissing the alert. */ timeoutAnimation?: number; /** Title of the alert. */ title: React.ReactNode; /** Sets the element to use as the alert title. Default is h4. */ component?: keyof JSX.IntrinsicElements; /** Adds accessible text to the alert toggle. */ toggleAriaLabel?: string; /** Position of the tooltip which is displayed if text is truncated. */ tooltipPosition?: | TooltipPosition | 'auto' | 'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'left-start' | 'left-end' | 'right-start' | 'right-end'; /** Truncate title to number of lines. */ truncateTitle?: number; /** Adds alert variant styles. */ variant?: 'success' | 'danger' | 'warning' | 'info' | 'custom'; /** Variant label text for screen readers. */ variantLabel?: string; /** Value to overwrite the randomly generated data-ouia-component-id.*/ ouiaId?: number | string; /** Set the value of data-ouia-safe. Only set to true when the component is in a static state, i.e. no animations are occurring. At all other times, this value must be false. */ ouiaSafe?: boolean; } export const Alert: React.FunctionComponent = ({ variant = AlertVariant.custom, isInline = false, isPlain = false, isLiveRegion = false, variantLabel = `${capitalize(variant)} alert:`, actionClose, actionLinks, title, component = 'h4', children = '', className = '', ouiaId, ouiaSafe = true, timeout = false, timeoutAnimation = 3000, onTimeout = () => {}, truncateTitle = 0, tooltipPosition, customIcon, isExpandable = false, toggleAriaLabel = `${capitalize(variant)} alert details`, onMouseEnter = () => {}, onMouseLeave = () => {}, id, ...props }: AlertProps) => { const ouiaProps = useOUIAProps(Alert.displayName, ouiaId, ouiaSafe, variant); const getHeadingContent = (