/**
 * 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_settings = require("../../settings.js");
const require_useClickOutside = require("../../global/js/hooks/useClickOutside.js");
const require_usePresence = require("../../global/js/hooks/usePresence.js");
const require_usePrefersReducedMotion = require("../../global/js/hooks/usePrefersReducedMotion.js");
const require_devtools = require("../../global/js/utils/devtools.js");
const require_props_helper = require("../../global/js/utils/props-helper.js");
const require_useId = require("../../global/js/utils/useId.js");
const require_NotificationsEmptyState = require("../EmptyStates/NotificationsEmptyState/NotificationsEmptyState.js");
const require_getSupportedLocale = require("../../global/js/utils/getSupportedLocale.js");
const require_utils = require("./utils.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");
let _carbon_react_icons = require("@carbon/react/icons");
let _carbon_utilities = require("@carbon/utilities");
//#region src/components/NotificationsPanel/NotificationsPanel.tsx
/**
* Copyright IBM Corp. 2020, 2022
*
* 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 componentName = "NotificationsPanel";
const blockClass = `${require_settings.pkg.prefix}--notifications-panel`;
const DefaultLocale = "en-US";
const defaults = {
	dateTimeStyle: "long",
	daysAgoText: (value) => `${value} days ago`,
	dismissAllLabel: "Dismiss all",
	dismissSingleNotificationIconDescription: "Dismiss",
	doNotDisturbLabel: "Do not disturb",
	emptyStateLabel: "You do not have any notifications",
	hourAgoText: (value) => `${value} hour ago`,
	hoursAgoText: (value) => `${value} hours ago`,
	illustrationTheme: "light",
	minuteAgoText: (value) => `${value} minute ago`,
	minutesAgoText: (value) => `${value} minutes ago`,
	monthAgoText: (value) => `${value} month ago`,
	monthsAgoText: (value) => `${value} months ago`,
	nowText: "Now",
	onDismissAllNotifications: () => {},
	onDismissSingleNotification: () => {},
	previousLabel: "Previous",
	readLessLabel: "Read less",
	readMoreLabel: "Read more",
	secondsAgoText: (value) => `${value} seconds ago`,
	settingsIconDescription: "Settings",
	title: "Notifications",
	todayLabel: "Today",
	viewAllLabel: (value) => `View all (${value})`,
	yearAgoText: (value) => `${value} year ago`,
	yearsAgoText: (value) => `${value} years ago`,
	yesterdayAtText: (value) => `Yesterday at ${value}`,
	yesterdayLabel: "Yesterday"
};
/**
* The `NotificationsPanel` sets expectations on the behavior for notifications,
* allowing the user to view and interact with them all in one place.
*
* **To adopt the new localization:**
*
* **Step 1:** Provide a locale to the `dateTimeLocale` prop, such as "de" or "fr-CA".
*
* **Step 2:** Remove the now _deprecated_ props: `daysAgoText`,
* `hourAgoText`, `hoursAgoText`, `minuteAgoText`, `minutesAgoText`,
* `monthAgoText`, `monthsAgoText`, `nowText`, `secondsAgoText`,
* `yearAgoText`, `yearsAgoText`, `yesterdayAtText`.
*
* If you do not provide a locale, the deprecated props will be applied instead.
*/
const NotificationsPanel = react.default.forwardRef(({ className, data, dateTimeLocale, dateTimeStyle = defaults.dateTimeStyle, daysAgoText = defaults.daysAgoText, dismissAllLabel = defaults.dismissAllLabel, dismissSingleNotificationIconDescription = defaults.dismissSingleNotificationIconDescription, doNotDisturbDefaultToggled, doNotDisturbLabel = defaults.doNotDisturbLabel, emptyStateLabel = defaults.emptyStateLabel, hourAgoText = defaults.hourAgoText, hoursAgoText = defaults.hoursAgoText, illustrationTheme = defaults.illustrationTheme, minuteAgoText = defaults.minuteAgoText, minutesAgoText = defaults.minutesAgoText, monthAgoText = defaults.monthAgoText, monthsAgoText = defaults.monthsAgoText, nowText = defaults.nowText, onClickOutside, onDismissAllNotifications = defaults.onDismissAllNotifications, onDismissSingleNotification = defaults.onDismissSingleNotification, onDoNotDisturbChange, onSettingsClick, onViewAllClick, open, previousLabel = defaults.previousLabel, readLessLabel = defaults.readLessLabel, readMoreLabel = defaults.readMoreLabel, secondsAgoText = defaults.secondsAgoText, settingsIconDescription = defaults.settingsIconDescription, title = defaults.title, todayLabel = defaults.todayLabel, viewAllLabel = defaults.viewAllLabel, yearAgoText = defaults.yearAgoText, yearsAgoText = defaults.yearsAgoText, yesterdayAtText = defaults.yesterdayAtText, yesterdayLabel = defaults.yesterdayLabel, triggerButtonRef, ...rest }, ref) => {
	const notificationPanelRef = (0, react.useRef)(null);
	const notificationPanelInnerRef = (0, react.useRef)(null);
	(0, react.useRef)(null);
	(0, react.useRef)(null);
	const [allNotifications, setAllNotifications] = (0, react.useState)([]);
	const supportedLocale = require_getSupportedLocale.getSupportedLocale(dateTimeLocale, DefaultLocale);
	(0, _carbon_react.usePrefix)();
	const headingId = require_useId.useId();
	const isClickOnTrigger = (0, react.useRef)(false);
	const { shouldRender } = require_usePresence.usePresence(open, notificationPanelRef, require_usePrefersReducedMotion.usePrefersReducedMotion() ? "notifications-panel-exit-reduced" : "notifications-panel-fade-out");
	(0, react.useEffect)(() => {
		setAllNotifications(data);
	}, [data]);
	(0, react.useEffect)(() => {
		const button = triggerButtonRef?.current;
		const handleClick = () => {
			isClickOnTrigger.current = true;
		};
		button?.addEventListener("click", handleClick, true);
		return () => {
			button?.removeEventListener("click", handleClick, true);
		};
	}, [triggerButtonRef]);
	require_useClickOutside.useClickOutside(ref || notificationPanelRef, (target) => {
		const element = target;
		if (!isClickOnTrigger.current) {
			if (!isActionableElement(element)) setTimeout(() => {
				triggerButtonRef?.current?.focus();
			}, 100);
			onClickOutside?.();
		}
		isClickOnTrigger.current = false;
	});
	const handleKeydown = (event) => {
		event.stopPropagation();
		if (event.key === "Escape") {
			onClickOutside?.();
			setTimeout(() => {
				triggerButtonRef?.current?.focus();
			}, 100);
		}
	};
	(0, react.useEffect)(() => {
		if (open) {
			const observer = new MutationObserver(() => {
				if (notificationPanelRef.current) {
					notificationPanelRef.current?.querySelector(`.${blockClass}__dismiss-button`)?.focus();
					observer.disconnect();
				}
			});
			if (notificationPanelRef.current) (notificationPanelRef.current?.querySelector(`.${blockClass}__dismiss-button`))?.focus();
			else observer.observe(document.body, {
				childList: true,
				subtree: true
			});
			return () => observer.disconnect();
		}
	}, [open]);
	const sortChronologically = (arr) => {
		if (!arr || arr && !arr.length) return;
		return arr.sort((a, b) => b.timestamp - a.timestamp);
	};
	let yesterdayDate = /* @__PURE__ */ new Date();
	yesterdayDate = new Date(yesterdayDate.setDate(yesterdayDate.getDate() - 1));
	let dayBeforeYesterdayDate = /* @__PURE__ */ new Date();
	dayBeforeYesterdayDate = new Date(dayBeforeYesterdayDate.setDate(dayBeforeYesterdayDate.getDate() - 2));
	let withinLastDayNotifications = allNotifications && allNotifications.length && allNotifications.filter((item) => item.timestamp.getTime() >= yesterdayDate.getTime());
	withinLastDayNotifications = sortChronologically(withinLastDayNotifications);
	let previousDayNotifications = allNotifications && allNotifications.length && allNotifications.filter((item) => item.timestamp.getTime() < yesterdayDate.getTime() && item.timestamp.getTime() >= dayBeforeYesterdayDate.getTime());
	previousDayNotifications = sortChronologically(previousDayNotifications);
	let previousNotifications = allNotifications && allNotifications.length && allNotifications.filter((item) => item.timestamp.getTime() < dayBeforeYesterdayDate.getTime());
	previousNotifications = sortChronologically(previousNotifications);
	const renderDescription = (id) => {
		const notification = allNotifications && allNotifications.length && allNotifications.filter((item) => item.id === id)[0];
		const trimLength = 88;
		const description = notification?.["description"];
		const descriptionClassName = (0, import_classnames.default)([`${blockClass}__notification-description`, {
			[`${blockClass}__notification-long-description`]: notification?.["showAll"],
			[`${blockClass}__notification-short-description`]: !notification?.["showAll"]
		}]);
		const showMoreButtonClassName = (0, import_classnames.default)([{
			[`${blockClass}__notification-read-less-button`]: notification?.["showAll"],
			[`${blockClass}__notification-read-more-button`]: !notification?.["showAll"]
		}]);
		return /* @__PURE__ */ react.default.createElement("div", null, /* @__PURE__ */ react.default.createElement("p", { className: descriptionClassName }, description), description.length > trimLength && /* @__PURE__ */ react.default.createElement(_carbon_react.Button, {
			kind: "ghost",
			size: "sm",
			renderIcon: (props) => /* @__PURE__ */ react.default.createElement(_carbon_react_icons.ChevronDown, {
				size: 16,
				...props
			}),
			iconDescription: notification?.["showAll"] ? readLessLabel : readMoreLabel,
			onClick: (event) => {
				event.preventDefault();
				event.stopPropagation();
				setAllNotifications(allNotifications.map((item) => {
					if (item.id === notification?.["id"]) return Object.assign({}, item, { showAll: !item?.["showAll"] });
					return item;
				}));
			},
			className: showMoreButtonClassName
		}, notification?.["showAll"] ? readLessLabel : readMoreLabel));
	};
	const renderNotification = (group, notification, index) => {
		const notificationClassName = (0, import_classnames.default)([`${blockClass}__notification`, `${blockClass}__notification-${group}`]);
		const notificationHeaderClassName = (0, import_classnames.default)([`${blockClass}__notification-title`, { [`${blockClass}__notification-title-unread`]: notification.unread }]);
		return /* @__PURE__ */ react.default.createElement(_carbon_react.Section, {
			key: `${notification.timestamp}-${notification.title}-${index}`,
			className: notificationClassName,
			as: "div",
			role: "button",
			tabIndex: 0,
			onClick: () => notification.onNotificationClick(notification),
			onKeyDown: (event) => {
				if (event.target instanceof HTMLElement && event.target.classList.contains(`${blockClass}__dismiss-single-button`)) return;
				if (event.which === 13) notification.onNotificationClick(notification);
			}
		}, notification.type === "error" && /* @__PURE__ */ react.default.createElement(_carbon_react_icons.ErrorFilled, {
			size: 16,
			className: (0, import_classnames.default)([`${blockClass}__notification-status-icon`, `${blockClass}__notification-status-icon-error`])
		}), notification.type === "success" && /* @__PURE__ */ react.default.createElement(_carbon_react_icons.CheckmarkFilled, {
			size: 16,
			className: (0, import_classnames.default)([`${blockClass}__notification-status-icon`, `${blockClass}__notification-status-icon-success`])
		}), notification.type === "warning" && /* @__PURE__ */ react.default.createElement(_carbon_react_icons.WarningAltFilled, {
			size: 16,
			className: (0, import_classnames.default)([`${blockClass}__notification-status-icon`, `${blockClass}__notification-status-icon-warning`])
		}), notification.type === "informational" && /* @__PURE__ */ react.default.createElement(_carbon_react_icons.InformationSquareFilled, {
			size: 16,
			className: (0, import_classnames.default)([`${blockClass}__notification-status-icon`, `${blockClass}__notification-status-icon-informational`])
		}), /* @__PURE__ */ react.default.createElement("div", { className: `${blockClass}__notification-content` }, /* @__PURE__ */ react.default.createElement("p", { className: `${blockClass}__notification-time-label` }, dateTimeLocale ? _carbon_utilities.dateTimeFormat.relative.format(notification.timestamp, {
			locale: supportedLocale,
			style: dateTimeStyle
		}) : require_utils.timeAgo({
			previousTime: notification.timestamp,
			secondsAgoText,
			minuteAgoText,
			minutesAgoText,
			hoursAgoText,
			hourAgoText,
			daysAgoText,
			yesterdayAtText,
			monthsAgoText,
			monthAgoText,
			yearsAgoText,
			yearAgoText,
			nowText
		})), /* @__PURE__ */ react.default.createElement(_carbon_react.Heading, { className: notificationHeaderClassName }, notification.title), notification.description && notification.description.length && renderDescription(notification.id), notification.link && notification.link.text && notification.link.url && /* @__PURE__ */ react.default.createElement(_carbon_react.Link, {
			href: notification.link.url,
			className: `${blockClass}__notifications-link`,
			...require_props_helper.prepareProps({}, notification.link, ["text", "url"])
		}, notification.link.text)), /* @__PURE__ */ react.default.createElement(_carbon_react.IconButton, {
			align: "left",
			kind: "ghost",
			size: "sm",
			label: dismissSingleNotificationIconDescription,
			className: `${blockClass}__dismiss-single-button`,
			onClick: (event) => dismissSingleNotification(event, notification)
		}, /* @__PURE__ */ react.default.createElement(_carbon_react_icons.Close, { size: 16 })));
	};
	const isActionableElement = (el) => {
		if (!el) return false;
		const interactiveRoles = new Set([
			"button",
			"link",
			"textbox",
			"checkbox",
			"radio",
			"slider",
			"spinbutton",
			"combobox",
			"switch",
			"menuitem"
		]);
		const actionableAncestor = el.closest("button, a, input, select, textarea, [tabindex], [contenteditable=\"true\"], [role]");
		if (!actionableAncestor) return false;
		return actionableAncestor instanceof HTMLButtonElement || actionableAncestor instanceof HTMLAnchorElement || actionableAncestor instanceof HTMLInputElement || actionableAncestor instanceof HTMLSelectElement || actionableAncestor instanceof HTMLTextAreaElement || actionableAncestor.tabIndex >= 0 || actionableAncestor.isContentEditable || interactiveRoles.has(actionableAncestor.getAttribute("role")?.toLowerCase() ?? "");
	};
	const dismissSingleNotification = (event, notification) => {
		event.preventDefault();
		event.stopPropagation();
		onDismissSingleNotification(notification);
	};
	const mainSectionClassName = (0, import_classnames.default)([`${blockClass}__main-section`, { [`${blockClass}__main-section-empty`]: allNotifications && !allNotifications.length }]);
	return shouldRender ? /* @__PURE__ */ react.default.createElement(_carbon_react.Section, {
		as: "div",
		role: "dialog",
		"aria-labelledby": headingId,
		onKeyDown: handleKeydown,
		...rest,
		id: blockClass,
		className: (0, import_classnames.default)(blockClass, className, `${blockClass}__container`, {
			[`${blockClass}__entrance`]: open,
			[`${blockClass}__exit`]: !open
		}),
		ref: ref || notificationPanelRef,
		...require_devtools.getDevtoolsProps(componentName)
	}, /* @__PURE__ */ react.default.createElement("div", { ref: notificationPanelInnerRef }, /* @__PURE__ */ react.default.createElement("div", { className: `${blockClass}__header-container` }, /* @__PURE__ */ react.default.createElement("div", { className: `${blockClass}__header-flex` }, /* @__PURE__ */ react.default.createElement(_carbon_react.Heading, {
		id: headingId,
		className: `${blockClass}__header`
	}, title), /* @__PURE__ */ react.default.createElement(_carbon_react.Button, {
		size: "sm",
		kind: "ghost",
		className: `${blockClass}__dismiss-button`,
		onClick: onDismissAllNotifications
	}, dismissAllLabel)), onDoNotDisturbChange && /* @__PURE__ */ react.default.createElement(_carbon_react.Toggle, {
		size: "sm",
		className: `${blockClass}__do-not-disturb-toggle`,
		id: `${blockClass}__do-not-disturb-toggle-component`,
		labelA: doNotDisturbLabel,
		labelB: doNotDisturbLabel,
		onToggle: (event) => onDoNotDisturbChange(event),
		defaultToggled: doNotDisturbDefaultToggled,
		"aria-label": doNotDisturbLabel,
		labelText: doNotDisturbLabel
	})), /* @__PURE__ */ react.default.createElement(_carbon_react.Section, { className: mainSectionClassName }, withinLastDayNotifications && withinLastDayNotifications.length ? /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, /* @__PURE__ */ react.default.createElement(_carbon_react.Heading, { className: `${blockClass}__time-section-label` }, todayLabel), withinLastDayNotifications.map((notification, index) => renderNotification("today", notification, index))) : null, previousDayNotifications && previousDayNotifications.length ? /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, /* @__PURE__ */ react.default.createElement(_carbon_react.Heading, { className: `${blockClass}__time-section-label` }, yesterdayLabel), previousDayNotifications.map((notification, index) => renderNotification("yesterday", notification, index))) : null, previousNotifications && previousNotifications.length ? /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, /* @__PURE__ */ react.default.createElement(_carbon_react.Heading, { className: `${blockClass}__time-section-label` }, previousLabel), previousNotifications.map((notification, index) => renderNotification("previous", notification, index))) : null, !allNotifications.length && /* @__PURE__ */ react.default.createElement(require_NotificationsEmptyState.NotificationsEmptyState, {
		illustrationTheme,
		title: "",
		subtitle: emptyStateLabel
	})), onViewAllClick && onSettingsClick && allNotifications && allNotifications.length > 0 && /* @__PURE__ */ react.default.createElement("div", { className: `${blockClass}__bottom-actions` }, /* @__PURE__ */ react.default.createElement(_carbon_react.Button, {
		kind: "ghost",
		className: `${blockClass}__view-all-button`,
		onClick: onViewAllClick
	}, viewAllLabel(allNotifications.length)), /* @__PURE__ */ react.default.createElement(_carbon_react.Button, {
		kind: "ghost",
		size: "sm",
		className: `${blockClass}__settings-button`,
		renderIcon: (props) => /* @__PURE__ */ react.default.createElement(_carbon_react_icons.Settings, {
			size: 16,
			...props
		}),
		iconDescription: settingsIconDescription,
		onClick: onSettingsClick,
		hasIconOnly: true,
		tooltipPosition: "left"
	})))) : null;
});
NotificationsPanel.displayName = componentName;
NotificationsPanel.propTypes = {
	/**
	* Provide an optional class to be applied to the containing node.
	*/
	className: prop_types.default.string,
	/**
	* Array of data for Notifications component to render
	*/
	/**@ts-ignore*/
	data: prop_types.default.arrayOf(prop_types.default.shape({
		id: prop_types.default.oneOfType([prop_types.default.string, prop_types.default.number]),
		type: prop_types.default.oneOf([
			"error",
			"warning",
			"success",
			"informational"
		]),
		timestamp: prop_types.default.instanceOf(Date),
		title: prop_types.default.string,
		description: prop_types.default.string,
		link: prop_types.default.shape({
			url: prop_types.default.string,
			text: prop_types.default.string
		}),
		unread: prop_types.default.bool,
		onNotificationClick: prop_types.default.func
	})).isRequired,
	/**
	* The language for each notification's time stamp.
	*/
	dateTimeLocale: prop_types.default.string,
	/**
	* The date/time format for each notification's time stamp.
	*
	* E.g. `long` as "6 minutes ago", `short` as "6m ago".
	*/
	dateTimeStyle: prop_types.default.string,
	/**
	* Sets the `days ago` label text
	*/
	daysAgoText: prop_types.default.func,
	/**
	* Label for Dismiss all button
	*/
	dismissAllLabel: prop_types.default.string,
	/**
	* Label for Dismiss single notification icon button
	*/
	dismissSingleNotificationIconDescription: prop_types.default.string,
	/**
	* Optional: Determines if the `Do not disturb` toggle is on or off when the component is rendered
	*/
	doNotDisturbDefaultToggled: prop_types.default.bool,
	/**
	* Optional: Label for Do not disturb toggle
	*/
	doNotDisturbLabel: prop_types.default.string,
	/**
	* Sets the empty state label text when there are no notifications
	*/
	emptyStateLabel: prop_types.default.string,
	/**
	* Sets the `hour ago` label text
	*/
	hourAgoText: prop_types.default.func,
	/**
	* Sets the `hours ago` label text
	*/
	hoursAgoText: prop_types.default.func,
	/**
	* Determines the theme of the empty state's illustration.
	*/
	illustrationTheme: prop_types.default.oneOf(["light", "dark"]),
	/**
	* Sets the `minute ago` label text
	*/
	minuteAgoText: prop_types.default.func,
	/**
	* Sets the `minutes ago` label text
	*/
	minutesAgoText: prop_types.default.func,
	/**
	* Sets the `month ago` label text
	*/
	monthAgoText: prop_types.default.func,
	/**
	* Sets the `months ago` label text
	*/
	monthsAgoText: prop_types.default.func,
	/**
	* Sets the `now` label text
	*/
	nowText: prop_types.default.string,
	/**
	* Optional function called after clicking outside of the panel.
	*/
	onClickOutside: prop_types.default.func,
	/**
	* Optional function called after clicking the "Dismiss all" button.
	*/
	onDismissAllNotifications: prop_types.default.func,
	/**
	* Optional function called after clicking a notification's "X" button.
	*/
	onDismissSingleNotification: prop_types.default.func,
	/**
	* Optional function called after toggling "Do not disturb".
	*/
	onDoNotDisturbChange: prop_types.default.func,
	/**
	* Optional function called after clicking settings / gear icon button.
	*/
	onSettingsClick: prop_types.default.func,
	/**
	* Optional function called after clicking the "View all" button.
	*/
	onViewAllClick: prop_types.default.func,
	/**
	* Determines whether the notifications panel should render or not
	*/
	open: prop_types.default.bool.isRequired,
	/**
	* Sets the previous label text
	*/
	previousLabel: prop_types.default.string,
	/**
	* Sets the `read less` label text
	*/
	readLessLabel: prop_types.default.string,
	/**
	* Sets the `read more` label text
	*/
	readMoreLabel: prop_types.default.string,
	/**
	* Sets the `seconds ago` label text
	*/
	secondsAgoText: prop_types.default.func,
	/**
	* Sets the settings icon description text
	*/
	settingsIconDescription: prop_types.default.string,
	/**
	* Sets the title for the Notifications panel
	*/
	title: prop_types.default.string,
	/**
	* Sets the today label text
	*/
	todayLabel: prop_types.default.string,
	/**
	* Sets the today label text
	*/
	triggerButtonRef: prop_types.default.any,
	/**
	* Sets the View all button text
	*/
	viewAllLabel: prop_types.default.func,
	/**
	* Sets the `year ago` label text
	*/
	yearAgoText: prop_types.default.func,
	/**
	* Sets the `years ago` label text
	*/
	yearsAgoText: prop_types.default.func,
	/**
	* Sets the `Yesterday at` label text
	*/
	yesterdayAtText: prop_types.default.func,
	/**
	* Sets the yesterday label text
	*/
	yesterdayLabel: prop_types.default.string
};
//#endregion
exports.NotificationsPanel = NotificationsPanel;
