/**
 * Copyright IBM Corp. 2020, 2026
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

const require_runtime = require('../../_virtual/_rolldown/runtime.js');
const require_index = require('../../node_modules/classnames/index.js');
const require_pconsole = require('../../global/js/utils/pconsole.js');
const require_settings = require('../../settings.js');
const require_useIsomorphicEffect = require('../../global/js/hooks/useIsomorphicEffect.js');
const require_usePreviousValue = require('../../global/js/hooks/usePreviousValue.js');
const require_useFocus = require('../../global/js/hooks/useFocus.js');
const require_props_helper = require('../../global/js/utils/props-helper.js');
const require_usePortalTarget = require('../../global/js/hooks/usePortalTarget.js');
const require_useResizeObserver = require('../../global/js/hooks/useResizeObserver.js');
const require_ActionSet = require('../ActionSet/ActionSet.js');
const require_getNodeTextContent = require('../../global/js/utils/getNodeTextContent.js');
const require_Wrap = require('../../global/js/utils/Wrap.js');
const require_useMergedRefs = require('../../global/js/hooks/useMergedRefs.js');
const require_useId = require('../../global/js/utils/useId.js');
const require_TearsheetPresence = require('./TearsheetPresence.js');
let react = require("react");
react = require_runtime.__toESM(react);
let prop_types = require("prop-types");
prop_types = require_runtime.__toESM(prop_types);
let _carbon_react = require("@carbon/react");

//#region src/components/Tearsheet/TearsheetShell.tsx
/**
* Copyright IBM Corp. 2020, 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
var import_classnames = /* @__PURE__ */ require_runtime.__toESM(require_index.default);
const bc = `${require_settings.pkg.prefix}--tearsheet`;
const componentName = "TearsheetShell";
const maxDepth = 3;
const stack = {
	open: [],
	all: [],
	sizes: []
};
const tearsheetShellWideProps = [
	"headerActions",
	"influencer",
	"influencerPosition",
	"influencerWidth",
	"navigation"
];
const tearsheetIsPassive = (actions) => !actions || !actions?.length;
const tearsheetHasCloseIcon = (actions, hasCloseIcon) => hasCloseIcon ?? tearsheetIsPassive(actions);
/**
* Since the Tearsheet has an H3 heading, any headings inside the Tearsheet should start at H4.
* This is a helper to do that.
*/
const SectionLevel3 = ({ children, ...rest }) => /* @__PURE__ */ react.default.createElement(_carbon_react.Section, {
	level: 3,
	...rest
}, children);
/**
*  TearSheetShell is used internally by TearSheet and TearSheetNarrow
*
* The component is not public.
*
* See the canvas tab for the component API details.
* */
const TearsheetShell = react.default.forwardRef(({ open, ...props }, ref) => {
	const id = require_useId.useId();
	const enablePresence = (0, _carbon_react.useFeatureFlag)("enable-presence");
	const hasPresenceContext = Boolean((0, react.useContext)(require_TearsheetPresence.TearsheetPresenceContext));
	const hasPresenceOptIn = enablePresence || hasPresenceContext;
	const exclusivePresenceContext = require_TearsheetPresence.useExclusiveTearsheetPresenceContext(id);
	if (hasPresenceOptIn && !exclusivePresenceContext) return /* @__PURE__ */ react.default.createElement(require_TearsheetPresence.TearsheetPresence, {
		open: open ?? false,
		_presenceId: id,
		_autoEnablePresence: hasPresenceContext
	}, /* @__PURE__ */ react.default.createElement(TearsheetShellDialog, {
		open: true,
		ref,
		...props
	}));
	return /* @__PURE__ */ react.default.createElement(TearsheetShellDialog, {
		ref,
		open,
		...props
	});
});
const TearsheetShellDialog = react.default.forwardRef(({ actions, decorator, ariaLabel, children, className, closeIconDescription = "Close", currentStep, description, hasCloseIcon, hasError, headerActions, influencer, influencerPosition, influencerWidth, label, navigation, onClose, open: externalOpen, portalTarget: portalTargetIn, selectorPrimaryFocus, selectorsFloatingMenus = [], size, slug: deprecated_slug, title, verticalPosition, launcherButtonRef, ...rest }, ref) => {
	const carbonPrefix = (0, _carbon_react.usePrefix)();
	const bcModalHeader = `${carbonPrefix}--modal-header`;
	const renderPortalUse = require_usePortalTarget.usePortalTarget(portalTargetIn);
	const localRef = (0, react.useRef)(void 0);
	const resizer = (0, react.useRef)(null);
	const modalBodyRef = (0, react.useRef)(null);
	const modalRef = ref || localRef;
	const { width } = require_useResizeObserver.useResizeObserver(resizer);
	const { keyDownListener, claimFocus } = require_useFocus.useFocus(modalRef, selectorPrimaryFocus);
	modalRef.current;
	const wide = size === "wide";
	const presenceContext = (0, react.useContext)(require_TearsheetPresence.TearsheetPresenceContext);
	const mergedRefs = require_useMergedRefs.useMergedRefs([modalRef, presenceContext?.presenceRef]);
	const enablePresence = (0, _carbon_react.useFeatureFlag)("enable-presence") || presenceContext?.autoEnablePresence;
	const open = externalOpen || enablePresence;
	const prevOpen = require_usePreviousValue.usePreviousValue(open);
	const [depth, setDepth] = (0, react.useState)(0);
	const [position, setPosition] = (0, react.useState)(0);
	const prevDepth = (0, react.useRef)(void 0);
	(0, react.useEffect)(() => {
		prevDepth.current = depth;
	});
	const isPassive = tearsheetIsPassive(actions);
	const effectiveHasCloseIcon = tearsheetHasCloseIcon(actions, hasCloseIcon);
	function handleStackChange(newDepth, newPosition) {
		setDepth(newDepth);
		setPosition(newPosition);
	}
	(0, react.useEffect)(() => {
		if (open) claimFocus();
	}, [
		open,
		currentStep,
		effectiveHasCloseIcon,
		claimFocus
	]);
	(0, react.useEffect)(() => {
		if (!enablePresence && prevOpen && !open && launcherButtonRef?.current) setTimeout(() => {
			launcherButtonRef?.current?.focus();
		}, 10);
	}, [
		enablePresence,
		open,
		prevOpen,
		launcherButtonRef
	]);
	(0, react.useEffect)(() => {
		const launcherButton = launcherButtonRef?.current;
		if (!enablePresence || !launcherButton) return;
		return () => {
			setTimeout(() => {
				launcherButton.focus();
			}, 10);
		};
	}, [enablePresence, launcherButtonRef]);
	(0, react.useEffect)(() => {
		requestAnimationFrame(() => {
			if (open && depth === position && !modalRef?.current?.contains(document.activeElement)) claimFocus();
		});
	}, [
		claimFocus,
		depth,
		modalRef,
		position
	]);
	(0, react.useEffect)(() => {
		if (hasError && !modalRef?.current?.contains(document.activeElement)) claimFocus();
	}, [
		claimFocus,
		hasError,
		modalRef
	]);
	(0, react.useEffect)(() => {
		const isPresent = open && !presenceContext?.isExiting;
		const notify = () => stack.all.forEach((handler) => {
			handler(Math.min(stack.open.length, maxDepth), stack.open.indexOf(handler) + 1);
		});
		stack.all.push(handleStackChange);
		stack.sizes.push(size);
		if (isPresent) {
			stack.open.push(handleStackChange);
			notify();
		}
		return function cleanup() {
			stack.all.splice(stack.all.indexOf(handleStackChange), 1);
			stack.sizes.splice(stack.sizes.indexOf(size), 1);
			const openIndex = stack.open.indexOf(handleStackChange);
			if (openIndex >= 0) {
				stack.open.splice(openIndex, 1);
				notify();
			}
		};
	}, [
		open,
		presenceContext?.isExiting,
		size
	]);
	const areAllSameSizeVariant = () => new Set(stack.sizes).size === 1;
	require_useIsomorphicEffect.useIsomorphicEffect(() => {
		const setScaleValues = () => {
			if (!areAllSameSizeVariant()) return {
				[`--${bc}--stacking-scale-factor-single`]: 1,
				[`--${bc}--stacking-scale-factor-double`]: 1
			};
			return {
				[`--${bc}--stacking-scale-factor-single`]: (width - 32) / width,
				[`--${bc}--stacking-scale-factor-double`]: (width - 64) / width
			};
		};
		if (modalRef.current) Object.entries(setScaleValues()).map(([key, value]) => {
			modalRef.current.style.setProperty(key, String(value));
		});
	}, [modalRef, width]);
	if (position <= depth) {
		const includeHeader = label || title || description || headerActions || navigation || effectiveHasCloseIcon;
		const includeActions = actions && actions?.length > 0;
		const areAllSameSizeVariant = () => new Set(stack.sizes).size === 1;
		return renderPortalUse(/* @__PURE__ */ react.default.createElement(_carbon_react.unstable_FeatureFlags, { enableExperimentalFocusWrapWithoutSentinels: true }, /* @__PURE__ */ react.default.createElement(_carbon_react.ComposedModal, {
			...rest,
			"aria-label": ariaLabel || require_getNodeTextContent.getNodeTextContent(title),
			className: (0, import_classnames.default)(bc, className, {
				[`${bc}--stacked-${position}-of-${depth}`]: depth > 1 || depth === 1 && (prevDepth?.current ?? 0) > 1,
				[`${bc}--wide`]: wide,
				[`${bc}--narrow`]: !wide,
				[`${bc}--has-slug`]: deprecated_slug,
				[`${bc}--has-ai-label`]: !!decorator && decorator["type"]?.displayName === "AILabel",
				[`${bc}--has-decorator`]: !!decorator && decorator["type"]?.displayName !== "AILabel",
				[`${bc}--has-close`]: effectiveHasCloseIcon,
				["is-visible"]: enablePresence,
				[`${bc}--tearsheet-enable-presence`]: presenceContext?.autoEnablePresence
			}),
			decorator: decorator || deprecated_slug,
			containerClassName: (0, import_classnames.default)(`${bc}__container`, {
				[`${bc}__container--lower`]: verticalPosition === "lower",
				[`${bc}__container--mixed-size-stacking`]: !areAllSameSizeVariant()
			}),
			onClose,
			open,
			selectorPrimaryFocus,
			onKeyDown: keyDownListener,
			preventCloseOnClickOutside: !isPassive,
			ref: mergedRefs,
			selectorsFloatingMenus: [
				`.${carbonPrefix}--overflow-menu-options`,
				`.${carbonPrefix}--tooltip`,
				".flatpickr-calendar",
				`.${bc}__container`,
				`.${carbonPrefix}--menu`,
				...selectorsFloatingMenus
			],
			size: "sm",
			"data-tearsheet-exiting": presenceContext?.isExiting || void 0
		}, includeHeader && /* @__PURE__ */ react.default.createElement(_carbon_react.ModalHeader, {
			className: (0, import_classnames.default)(`${bc}__header`, {
				[`${bc}__header--with-close-icon`]: effectiveHasCloseIcon,
				[`${bc}__header--with-nav`]: navigation
			}),
			closeClassName: (0, import_classnames.default)({ [`${bc}__header--no-close-icon`]: !effectiveHasCloseIcon }),
			closeModal: onClose,
			iconDescription: effectiveHasCloseIcon ? closeIconDescription : void 0
		}, /* @__PURE__ */ react.default.createElement(require_Wrap.Wrap, {
			className: `${bc}__header-content`,
			element: wide ? _carbon_react.Layer : void 0
		}, /* @__PURE__ */ react.default.createElement(require_Wrap.Wrap, { className: `${bc}__header-fields` }, /* @__PURE__ */ react.default.createElement(require_Wrap.Wrap, { className: `${bcModalHeader}__label` }, label), /* @__PURE__ */ react.default.createElement(require_Wrap.Wrap, {
			element: "h3",
			className: (0, import_classnames.default)(`${bcModalHeader}__heading`, `${bc}__heading`)
		}, title), /* @__PURE__ */ react.default.createElement(require_Wrap.Wrap, { className: `${bc}__header-description` }, description)), /* @__PURE__ */ react.default.createElement(require_Wrap.Wrap, { className: `${bc}__header-actions` }, headerActions)), /* @__PURE__ */ react.default.createElement(require_Wrap.Wrap, { className: `${bc}__header-navigation` }, navigation)), /* @__PURE__ */ react.default.createElement(require_Wrap.Wrap, {
			ref: modalBodyRef,
			className: `${carbonPrefix}--modal-content ${bc}__body`
		}, /* @__PURE__ */ react.default.createElement(require_Wrap.Wrap, {
			className: (0, import_classnames.default)({
				[`${bc}__influencer`]: true,
				[`${bc}__influencer--wide`]: influencerWidth === "wide"
			}),
			neverRender: influencerPosition === "right",
			element: SectionLevel3
		}, /* @__PURE__ */ react.default.createElement(require_Wrap.Wrap, {
			element: _carbon_react.Layer,
			className: `${bc}__layer`
		}, influencer)), /* @__PURE__ */ react.default.createElement(require_Wrap.Wrap, { className: `${bc}__right` }, /* @__PURE__ */ react.default.createElement(require_Wrap.Wrap, {
			className: `${bc}__main`,
			alwaysRender: includeActions
		}, /* @__PURE__ */ react.default.createElement(require_Wrap.Wrap, {
			className: `${bc}__content`,
			alwaysRender: !!(influencer && influencerPosition === "right"),
			element: SectionLevel3
		}, wide ? children : /* @__PURE__ */ react.default.createElement(require_Wrap.Wrap, {
			element: _carbon_react.Layer,
			className: `${bc}__layer`
		}, children)), /* @__PURE__ */ react.default.createElement(require_Wrap.Wrap, {
			className: (0, import_classnames.default)({
				[`${bc}__influencer`]: true,
				[`${bc}__influencer--wide`]: influencerWidth === "wide"
			}),
			neverRender: influencerPosition !== "right",
			element: SectionLevel3
		}, /* @__PURE__ */ react.default.createElement(require_Wrap.Wrap, {
			element: _carbon_react.Layer,
			className: `${bc}__layer`
		}, influencer))), includeActions && /* @__PURE__ */ react.default.createElement(require_Wrap.Wrap, { className: `${bc}__button-container` }, /* @__PURE__ */ react.default.createElement(require_ActionSet.ActionSet, {
			actions,
			buttonSize: wide ? "2xl" : void 0,
			className: `${bc}__buttons`,
			size: wide ? "2xl" : "lg",
			"aria-hidden": !open
		})))), /* @__PURE__ */ react.default.createElement("div", {
			className: `${bc}__resize-detector`,
			ref: resizer
		}))));
	} else {
		require_pconsole.default.warn("Tearsheet not rendered: maximum stacking depth exceeded.");
		return null;
	}
});
TearsheetShell.displayName = componentName;
const portalType = typeof Element === "undefined" ? prop_types.default.object : prop_types.default.instanceOf(Element);
const deprecatedProps = {
	slug: require_props_helper.deprecateProp(prop_types.default.node, "Property replaced by `decorator`"),
	verticalPosition: prop_types.default.oneOf(["normal", "lower"])
};
TearsheetShell.propTypes = {
	actions: prop_types.default.arrayOf(prop_types.default.shape({
		..._carbon_react.Button.propTypes,
		kind: prop_types.default.oneOf([
			"ghost",
			"danger--ghost",
			"secondary",
			"danger",
			"primary"
		]),
		label: prop_types.default.string,
		loading: prop_types.default.bool,
		onClick: _carbon_react.Button.propTypes.onClick
	})),
	children: prop_types.default.node,
	className: prop_types.default.string,
	closeIconDescription: prop_types.default.string,
	decorator: prop_types.default.oneOfType([prop_types.default.node, prop_types.default.bool]),
	description: prop_types.default.node,
	hasCloseIcon: prop_types.default.bool,
	headerActions: prop_types.default.element,
	influencer: prop_types.default.element,
	influencerPosition: prop_types.default.oneOf(["left", "right"]),
	influencerWidth: prop_types.default.oneOf(["narrow", "wide"]),
	label: prop_types.default.node,
	launcherButtonRef: prop_types.default.any,
	navigation: prop_types.default.element,
	onClose: prop_types.default.func,
	open: prop_types.default.bool,
	portalTarget: portalType,
	selectorPrimaryFocus: prop_types.default.string,
	selectorsFloatingMenus: prop_types.default.arrayOf(prop_types.default.string),
	size: prop_types.default.oneOf(["narrow", "wide"]).isRequired,
	title: prop_types.default.node,
	...deprecatedProps
};

//#endregion
exports.TearsheetShell = TearsheetShell;
exports.portalType = portalType;
exports.tearsheetShellWideProps = tearsheetShellWideProps;