{"version":3,"file":"Modal.mjs","sources":["../../../../src/components/Modal/Modal.tsx"],"sourcesContent":["import { cx } from '@emotion/css';\nimport { FloatingFocusManager, useDismiss, useFloating, useInteractions, useRole } from '@floating-ui/react';\nimport { OverlayContainer } from '@react-aria/overlays';\nimport { PropsWithChildren, ReactNode, useId, type JSX } from 'react';\n\nimport { t } from '@grafana/i18n';\n\nimport { useStyles2 } from '../../themes/ThemeContext';\nimport { IconName } from '../../types/icon';\nimport { IconButton } from '../IconButton/IconButton';\nimport { Stack } from '../Layout/Stack/Stack';\nimport { getPortalContainer } from '../Portal/Portal';\n\nimport { ModalHeader } from './ModalHeader';\nimport { getModalStyles } from './getModalStyles';\n\ninterface BaseProps {\n  /** @deprecated no longer used */\n  icon?: IconName;\n  /** @deprecated no longer used */\n  iconTooltip?: string;\n  className?: string;\n  contentClassName?: string;\n  closeOnEscape?: boolean;\n  closeOnBackdropClick?: boolean;\n  trapFocus?: boolean;\n\n  isOpen?: boolean;\n  onDismiss?: () => void;\n\n  /** If not set will call onDismiss if that is set. */\n  onClickBackdrop?: () => void;\n}\n\ninterface WithStringTitleProps extends BaseProps {\n  /** Title for the modal or custom header element */\n  title: string;\n  ariaLabel?: never;\n}\n\ninterface WithCustomTitleProps extends BaseProps {\n  /** Title for the modal or custom header element */\n  title: JSX.Element;\n  /** aria-label for the dialog. only needed when passing a custom title element */\n  ariaLabel: string;\n}\n\nexport type Props = WithStringTitleProps | WithCustomTitleProps;\n\n/**\n * https://developers.grafana.com/ui/latest/index.html?path=/docs/overlays-modal--docs\n */\nexport function Modal(props: PropsWithChildren<Props>) {\n  const {\n    title,\n    ariaLabel,\n    children,\n    isOpen = false,\n    closeOnEscape = true,\n    closeOnBackdropClick = true,\n    className,\n    contentClassName,\n    onDismiss,\n    onClickBackdrop,\n    trapFocus = true,\n  } = props;\n  const styles = useStyles2(getModalStyles);\n  const titleId = useId();\n\n  const { context, refs } = useFloating({\n    open: isOpen,\n    onOpenChange: (open) => {\n      if (!open) {\n        onDismiss?.();\n      }\n    },\n  });\n\n  const dismiss = useDismiss(context, {\n    enabled: closeOnEscape,\n  });\n\n  const role = useRole(context, {\n    role: 'dialog',\n  });\n\n  const { getFloatingProps } = useInteractions([dismiss, role]);\n\n  if (!isOpen) {\n    return null;\n  }\n\n  const headerClass = cx(styles.modalHeader, typeof title !== 'string' && styles.modalHeaderWithTabs);\n\n  return (\n    <OverlayContainer>\n      <div\n        role=\"presentation\"\n        className={styles.modalBackdrop}\n        onClick={onClickBackdrop || (closeOnBackdropClick ? onDismiss : undefined)}\n      />\n      <FloatingFocusManager context={context} modal={trapFocus} getInsideElements={() => [getPortalContainer()]}>\n        <div\n          className={cx(styles.modal, className)}\n          ref={refs.setFloating}\n          aria-label={ariaLabel}\n          aria-labelledby={typeof title === 'string' ? titleId : undefined}\n          {...getFloatingProps()}\n        >\n          <div className={headerClass}>\n            {typeof title === 'string' && <DefaultModalHeader {...props} title={title} id={titleId} />}\n            {\n              // FIXME: custom title components won't get an accessible title.\n              // Do we really want to support them or shall we just limit this ModalTabsHeader?\n              typeof title !== 'string' && title\n            }\n            <div className={styles.modalHeaderClose}>\n              <IconButton\n                name=\"times\"\n                size=\"xl\"\n                onClick={onDismiss}\n                aria-label={t('grafana-ui.modal.close-tooltip', 'Close')}\n              />\n            </div>\n          </div>\n          <div className={cx(styles.modalContent, contentClassName)}>{children}</div>\n        </div>\n      </FloatingFocusManager>\n    </OverlayContainer>\n  );\n}\n\nfunction ModalButtonRow({ leftItems, children }: { leftItems?: ReactNode; children: ReactNode }) {\n  const styles = useStyles2(getModalStyles);\n\n  if (leftItems) {\n    return (\n      <div className={styles.modalButtonRow}>\n        <Stack justifyContent=\"space-between\">\n          <Stack justifyContent=\"flex-start\" gap={2}>\n            {leftItems}\n          </Stack>\n          <Stack justifyContent=\"flex-end\" gap={2}>\n            {children}\n          </Stack>\n        </Stack>\n      </div>\n    );\n  }\n\n  return (\n    <div className={styles.modalButtonRow}>\n      <Stack justifyContent=\"flex-end\" gap={2} wrap=\"wrap\">\n        {children}\n      </Stack>\n    </div>\n  );\n}\n\nModal.ButtonRow = ModalButtonRow;\n\ninterface DefaultModalHeaderProps {\n  id?: string;\n  title: string;\n  icon?: IconName;\n  iconTooltip?: string;\n}\n\nfunction DefaultModalHeader({ icon, iconTooltip, title, id }: DefaultModalHeaderProps): JSX.Element {\n  return <ModalHeader icon={icon} iconTooltip={iconTooltip} title={title} id={id} />;\n}\n"],"names":[],"mappings":"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"}