diff --git a/packages/react/src/components/ComposedModal/ComposedModal.featureflag.mdx b/packages/react/src/components/ComposedModal/ComposedModal.featureflag.mdx index 9e731d397a28..3b4d8cda9093 100644 --- a/packages/react/src/components/ComposedModal/ComposedModal.featureflag.mdx +++ b/packages/react/src/components/ComposedModal/ComposedModal.featureflag.mdx @@ -95,3 +95,16 @@ to a different level: ``` + +Instead of wrapping your component with `ComposedModalPresence`, you can also use the higher-order function `withComposedModalPresence`. +This will automatically wrap your component and handle the props as well as their types for you: + +```jsx +export const MyComposedModal = withComposedModalPresence( + ({ onSubmit, onClose }) => { + ... + }, +); + + +``` diff --git a/packages/react/src/components/ComposedModal/ComposedModalPresence.tsx b/packages/react/src/components/ComposedModal/ComposedModalPresence.tsx index c0e4d3b762ff..9f8727a826b2 100644 --- a/packages/react/src/components/ComposedModal/ComposedModalPresence.tsx +++ b/packages/react/src/components/ComposedModal/ComposedModalPresence.tsx @@ -9,6 +9,8 @@ import React, { createContext, useContext, useMemo, + type ComponentType, + type FC, type PropsWithChildren, } from 'react'; import { @@ -80,3 +82,28 @@ export const useExclusiveComposedModalPresenceContext = (id: string) => { const ctx = useContext(ComposedModalPresenceContext); return ctx?.isPresenceExclusive(id) ? ctx : undefined; }; + +type WithComposedModalPresenceProps = Pick; + +/** + * Higher-order function that wraps a component with ComposedModalPresence + */ +export const withComposedModalPresence = ( + Component: ComponentType +): FC => { + const WithComposedModalPresence: FC< + TProps & WithComposedModalPresenceProps + > = (props) => { + const { open, ...componentProps } = props; + + return ( + + + + ); + }; + + WithComposedModalPresence.displayName = `withComposedModalPresence(${Component.displayName || Component.name || 'Component'})`; + + return WithComposedModalPresence; +}; diff --git a/packages/react/src/components/ComposedModal/index.tsx b/packages/react/src/components/ComposedModal/index.tsx index fe29537ca9d7..6963d3e3dd31 100644 --- a/packages/react/src/components/ComposedModal/index.tsx +++ b/packages/react/src/components/ComposedModal/index.tsx @@ -13,6 +13,7 @@ export { } from './ComposedModal'; export { ComposedModalPresence, + withComposedModalPresence, type ComposedModalPresenceProps, } from './ComposedModalPresence'; diff --git a/packages/react/src/components/Modal/Modal.featureflag.mdx b/packages/react/src/components/Modal/Modal.featureflag.mdx index 7417e558ab54..1b11ee9620a9 100644 --- a/packages/react/src/components/Modal/Modal.featureflag.mdx +++ b/packages/react/src/components/Modal/Modal.featureflag.mdx @@ -97,3 +97,16 @@ different level: ``` + +Instead of wrapping your component with `ModalPresence`, you can also use the higher-order function `withModalPresence`. +This will automatically wrap your component and handle the props as well as their types for you: + +```jsx +export const MyModal = withModalPresence( + ({ onSubmit, onClose }) => { + ... + }, +); + + +``` diff --git a/packages/react/src/components/Modal/ModalPresence.tsx b/packages/react/src/components/Modal/ModalPresence.tsx index fbf72e809f60..db9b9b0feb5f 100644 --- a/packages/react/src/components/Modal/ModalPresence.tsx +++ b/packages/react/src/components/Modal/ModalPresence.tsx @@ -9,6 +9,8 @@ import React, { createContext, useContext, useMemo, + type ComponentType, + type FC, type PropsWithChildren, } from 'react'; import { @@ -73,3 +75,26 @@ export const useExclusiveModalPresenceContext = (id: string) => { const ctx = useContext(ModalPresenceContext); return ctx?.isPresenceExclusive(id) ? ctx : undefined; }; + +type WithModalPresenceProps = Pick; + +/** + * Higher-order function that wraps a component with ModalPresence + */ +export const withModalPresence = ( + Component: ComponentType +): FC => { + const WithModalPresence: FC = (props) => { + const { open, ...componentProps } = props; + + return ( + + + + ); + }; + + WithModalPresence.displayName = `withModalPresence(${Component.displayName || Component.name || 'Component'})`; + + return WithModalPresence; +}; diff --git a/packages/react/src/components/Modal/index.ts b/packages/react/src/components/Modal/index.ts index 3376928cf848..f16d15a13400 100644 --- a/packages/react/src/components/Modal/index.ts +++ b/packages/react/src/components/Modal/index.ts @@ -5,7 +5,17 @@ * LICENSE file in the root directory of this source tree. */ import Modal, { type ModalProps } from './Modal'; -import { ModalPresence, type ModalPresenceProps } from './ModalPresence'; +import { + ModalPresence, + withModalPresence, + type ModalPresenceProps, +} from './ModalPresence'; export default Modal; -export { Modal, ModalPresence, type ModalProps, type ModalPresenceProps }; +export { + Modal, + ModalPresence, + withModalPresence, + type ModalProps, + type ModalPresenceProps, +};