"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.CENTERED_DIALOG_BACKDROP_TESTID = void 0;
exports.CenteredDialog = CenteredDialog;
var _react = _interopRequireWildcard(require("react"));
var _reactNative = require("react-native");
var _useInteractionState = require("../hooks/useInteractionState.js");
var _Times = require("../icons/Times.js");
var _useTheme = require("../theme/use-theme.js");
var _index = require("../typography/index.js");
var _centeredDialogTokens = require("./centered-dialog-tokens.js");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
const CLOSE_HIT_SLOP = {
  top: 8,
  bottom: 8,
  left: 8,
  right: 8
};

/** Stable testID for the dimmed backdrop. Overridden when a `testID` is set. */
const CENTERED_DIALOG_BACKDROP_TESTID = exports.CENTERED_DIALOG_BACKDROP_TESTID = 'bloom-centered-dialog-backdrop';

/**
 * Native variant of `<CenteredDialog>`.
 *
 * A controlled, centered modal: a transparent RN `Modal` (fade animation,
 * own native window) hosting a dimmed full-screen backdrop and a centered,
 * rounded card styled entirely from Bloom theme tokens.
 *
 * The backdrop is a sibling `Pressable` rendered BEHIND the card (absolute
 * filled), never a parent of it — so a tap on the card never bubbles to the
 * backdrop's close handler and the card never ends up nested inside the
 * backdrop's pressable on web.
 *
 * Dismissal: backdrop tap (when `dismissible`), the header close button, and
 * the Android hardware back button (`onRequestClose`) all call `onClose`.
 */
function CenteredDialog({
  visible,
  onClose,
  title,
  dismissible = true,
  maxWidth = _centeredDialogTokens.DEFAULT_MAX_WIDTH,
  compact = true,
  showClose,
  children,
  footer,
  accessibilityLabel,
  closeAccessibilityLabel = 'Close dialog',
  backdropAccessibilityLabel = 'Dismiss dialog',
  cardStyle,
  contentStyle,
  testID
}) {
  const theme = (0, _useTheme.useTheme)();
  const backdropPress = (0, _useInteractionState.useInteractionState)();
  const spacing = (0, _react.useMemo)(() => (0, _centeredDialogTokens.resolveSpacing)(compact), [compact]);
  const resolvedShowClose = showClose ?? Boolean(title);
  const hasHeader = Boolean(title) || resolvedShowClose;
  const handleBackdropPress = dismissible ? onClose : undefined;
  // Android's hardware back must always be answerable; when the dialog is
  // non-dismissible we still need a handler (RN requires one for transparent
  // modals) — make it a no-op so back does nothing rather than crash.
  const handleRequestClose = dismissible ? onClose : noop;
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Modal, {
    visible: visible,
    transparent: true,
    animationType: "fade",
    statusBarTranslucent: true,
    onRequestClose: handleRequestClose,
    children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
      style: [styles.root, {
        padding: _centeredDialogTokens.VIEWPORT_GUTTER
      }],
      children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
        testID: testID ? `${testID}-backdrop` : CENTERED_DIALOG_BACKDROP_TESTID,
        style: [styles.backdrop, {
          backgroundColor: theme.colors.overlay
        }, backdropPress.state && styles.backdropPressed],
        onPress: handleBackdropPress,
        onPressIn: backdropPress.onIn,
        onPressOut: backdropPress.onOut,
        disabled: !dismissible,
        accessibilityRole: "button",
        accessibilityLabel: backdropAccessibilityLabel
      }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
        testID: testID,
        accessibilityLabel: accessibilityLabel ?? title,
        style: [styles.card, {
          maxWidth,
          maxHeight: `${_centeredDialogTokens.MAX_HEIGHT_FRACTION * 100}%`,
          backgroundColor: theme.colors.card,
          borderColor: theme.colors.border,
          shadowColor: theme.colors.shadow
        }, cardStyle],
        children: [hasHeader ? /*#__PURE__*/(0, _jsxRuntime.jsx)(DialogHeader, {
          title: title,
          showClose: resolvedShowClose,
          padding: spacing.pad,
          gap: spacing.headerGap,
          closeAccessibilityLabel: closeAccessibilityLabel,
          onClose: onClose
        }) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
          style: styles.bodyScroll,
          contentContainerStyle: [{
            padding: spacing.pad,
            paddingTop: hasHeader ? spacing.headerGap : spacing.pad,
            gap: spacing.contentGap
          }, contentStyle],
          showsVerticalScrollIndicator: false,
          keyboardShouldPersistTaps: "handled",
          children: children
        }), footer ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
          style: [styles.footer, {
            padding: spacing.pad,
            paddingTop: spacing.footerGap,
            borderTopColor: theme.colors.borderLight
          }],
          children: footer
        }) : null]
      })]
    })
  });
}
function DialogHeader({
  title,
  showClose,
  padding,
  gap,
  closeAccessibilityLabel,
  onClose
}) {
  const theme = (0, _useTheme.useTheme)();
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
    style: [styles.header, {
      paddingHorizontal: padding,
      paddingTop: padding,
      gap
    }],
    children: [title ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.Text, {
      accessibilityRole: "header",
      numberOfLines: 2,
      style: [styles.title, {
        color: theme.colors.text
      }],
      children: title
    }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
      style: styles.titleSpacer
    }), showClose ? /*#__PURE__*/(0, _jsxRuntime.jsx)(CloseButton, {
      accessibilityLabel: closeAccessibilityLabel,
      onPress: onClose
    }) : null]
  });
}
function CloseButton({
  accessibilityLabel,
  onPress
}) {
  const theme = (0, _useTheme.useTheme)();
  const press = (0, _useInteractionState.useInteractionState)();
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
    onPress: onPress,
    onPressIn: press.onIn,
    onPressOut: press.onOut,
    hitSlop: CLOSE_HIT_SLOP,
    accessibilityRole: "button",
    accessibilityLabel: accessibilityLabel,
    style: [styles.closeButton, {
      backgroundColor: theme.colors.contrast50
    }, press.state && styles.closeButtonPressed],
    children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Times.TimesLarge_Stroke2_Corner0_Rounded, {
      size: "sm",
      fill: theme.colors.textSecondary
    })
  });
}
function noop() {
  /* non-dismissible: hardware back is intentionally inert */
}
const styles = _reactNative.StyleSheet.create({
  root: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center'
  },
  backdrop: {
    // Spell out the absolute-fill rect (matches `Fill`'s canonical style)
    // rather than spreading the deprecated `StyleSheet.absoluteFillObject`,
    // which RN 0.83's generated types no longer surface on the `StyleSheet`
    // namespace and which downstream type-checks reject.
    position: 'absolute',
    top: 0,
    right: 0,
    bottom: 0,
    left: 0
  },
  // A subtle deepening on press confirms the tap-to-dismiss affordance.
  backdropPressed: {
    opacity: 0.92
  },
  card: {
    width: '100%',
    borderRadius: _centeredDialogTokens.CARD_RADIUS,
    borderWidth: _reactNative.StyleSheet.hairlineWidth,
    overflow: 'hidden',
    shadowOpacity: 0.18,
    shadowRadius: 24,
    shadowOffset: {
      width: 0,
      height: 8
    },
    elevation: 12
  },
  header: {
    flexDirection: 'row',
    alignItems: 'flex-start',
    justifyContent: 'space-between'
  },
  title: {
    flex: 1,
    fontSize: 17,
    fontWeight: '700',
    lineHeight: 22
  },
  titleSpacer: {
    flex: 1
  },
  closeButton: {
    width: 28,
    height: 28,
    borderRadius: 14,
    alignItems: 'center',
    justifyContent: 'center'
  },
  closeButtonPressed: {
    opacity: 0.7
  },
  bodyScroll: {
    flexGrow: 0,
    flexShrink: 1
  },
  footer: {
    borderTopWidth: _reactNative.StyleSheet.hairlineWidth
  }
});
//# sourceMappingURL=CenteredDialog.js.map