diff --git a/packages/react/src/components/ComposedModal/ComposedModal.tsx b/packages/react/src/components/ComposedModal/ComposedModal.tsx
index b0019f672f82..6195b1c93ae9 100644
--- a/packages/react/src/components/ComposedModal/ComposedModal.tsx
+++ b/packages/react/src/components/ComposedModal/ComposedModal.tsx
@@ -8,6 +8,8 @@ import React, {
type ReactNode,
type ReactElement,
type RefObject,
+ useMemo,
+ isValidElement,
} from 'react';
import { isElement } from 'react-is';
import PropTypes from 'prop-types';
@@ -28,6 +30,7 @@ import { usePrefix } from '../../internal/usePrefix';
import { keys, match } from '../../internal/keyboard';
import { useFeatureFlag } from '../FeatureFlags';
import { composeEventHandlers } from '../../tools/events';
+import deprecate from '../../prop-types/deprecate';
export interface ModalBodyProps extends HTMLAttributes {
/** Specify the content to be placed in the ModalBody. */
@@ -172,6 +175,11 @@ export interface ComposedModalProps extends HTMLAttributes {
*/
danger?: boolean;
+ /**
+ * **Experimental**: Provide a `decorator` component to be rendered inside the `ComposedModal` component
+ */
+ decorator?: ReactNode;
+
/**
* Specify whether the Modal content should have any inner padding.
*/
@@ -212,6 +220,7 @@ export interface ComposedModalProps extends HTMLAttributes {
size?: 'xs' | 'sm' | 'md' | 'lg';
/**
+ * @deprecated please use `decorator` instead.
* **Experimental**: Provide a `Slug` component to be rendered inside the `ComposedModal` component
*/
slug?: ReactNode;
@@ -226,6 +235,7 @@ const ComposedModal = React.forwardRef(
className: customClassName,
containerClassName,
danger,
+ decorator,
isFullWidth,
onClose,
onKeyDown,
@@ -335,6 +345,7 @@ const ComposedModal = React.forwardRef(
'is-visible': isOpen,
[`${prefix}--modal--danger`]: danger,
[`${prefix}--modal--slug`]: slug,
+ [`${prefix}--modal--decorator`]: decorator,
},
customClassName
);
@@ -421,12 +432,20 @@ const ComposedModal = React.forwardRef(
}
}, [open, selectorPrimaryFocus, isOpen]);
- // Slug is always size `sm`
- let normalizedSlug;
- if (slug && slug['type']?.displayName === 'AILabel') {
- normalizedSlug = React.cloneElement(slug as React.ReactElement, {
- size: 'sm',
- });
+ // AILabel is always size `sm`
+ let normalizedDecorator = React.isValidElement(slug ?? decorator)
+ ? (slug ?? decorator)
+ : null;
+ if (
+ normalizedDecorator &&
+ normalizedDecorator['type']?.displayName === 'AILabel'
+ ) {
+ normalizedDecorator = React.cloneElement(
+ normalizedDecorator as React.ReactElement,
+ {
+ size: 'sm',
+ }
+ );
}
return (
@@ -456,7 +475,15 @@ const ComposedModal = React.forwardRef(
)}
- {normalizedSlug}
+ {slug ? (
+ normalizedDecorator
+ ) : decorator ? (
+
+ {normalizedDecorator}
+
+ ) : (
+ ''
+ )}
{childrenWithProps}
{/* Non-translatable: Focus-wrap code makes this `