From affd20438403d319ad1341d772b46eadf6f8dbdb Mon Sep 17 00:00:00 2001 From: Eduard Fischer-Szava Date: Sat, 30 May 2026 02:14:45 +0200 Subject: [PATCH] feat(react): add generic type parameter to useIonModal and useIonPopover Add overloaded function signatures to useIonModal and useIonPopover so that TypeScript can infer componentProps type from the component argument. When a React ComponentClass or FC is provided, componentProps is typed as that component's props type (P). When a JSX.Element is passed, any is used to preserve existing behaviour. The default for P remains any to avoid breaking changes. Resolves #28680 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- packages/react/src/hooks/useIonModal.ts | 8 ++++++-- packages/react/src/hooks/useIonPopover.ts | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/react/src/hooks/useIonModal.ts b/packages/react/src/hooks/useIonModal.ts index aee3ea40e40..6b267fc62d6 100644 --- a/packages/react/src/hooks/useIonModal.ts +++ b/packages/react/src/hooks/useIonModal.ts @@ -1,6 +1,7 @@ import type { ModalOptions } from '@ionic/core/components'; import { modalController } from '@ionic/core/components'; import { defineCustomElement } from '@ionic/core/components/ion-modal.js'; +import type React from 'react'; import { useCallback } from 'react'; import type { ReactComponentOrElement } from '../models/ReactComponentOrElement'; @@ -8,14 +9,17 @@ import type { ReactComponentOrElement } from '../models/ReactComponentOrElement' import type { HookOverlayOptions } from './HookOverlayOptions'; import { useOverlay } from './useOverlay'; -// TODO(FW-2959): types - /** * A hook for presenting/dismissing an IonModal component * @param component The component that the modal will show. Can be a React Component, a functional component, or a JSX Element * @param componentProps The props that will be passed to the component, if required * @returns Returns the present and dismiss methods in an array */ +export function useIonModal>( + component: React.ComponentClass | React.FC, + componentProps?: T +): UseIonModalResult; +export function useIonModal(component: JSX.Element, componentProps?: any): UseIonModalResult; export function useIonModal(component: ReactComponentOrElement, componentProps?: any): UseIonModalResult { const controller = useOverlay( 'IonModal', diff --git a/packages/react/src/hooks/useIonPopover.ts b/packages/react/src/hooks/useIonPopover.ts index c63df7b26e0..9bbf354a95e 100644 --- a/packages/react/src/hooks/useIonPopover.ts +++ b/packages/react/src/hooks/useIonPopover.ts @@ -1,6 +1,7 @@ import type { PopoverOptions } from '@ionic/core/components'; import { popoverController } from '@ionic/core/components'; import { defineCustomElement } from '@ionic/core/components/ion-popover.js'; +import type React from 'react'; import { useCallback } from 'react'; import type { ReactComponentOrElement } from '../models/ReactComponentOrElement'; @@ -8,14 +9,17 @@ import type { ReactComponentOrElement } from '../models/ReactComponentOrElement' import type { HookOverlayOptions } from './HookOverlayOptions'; import { useOverlay } from './useOverlay'; -// TODO(FW-2959): types - /** * A hook for presenting/dismissing an IonPicker component * @param component The component that the popover will show. Can be a React Component, a functional component, or a JSX Element * @param componentProps The props that will be passed to the component, if required * @returns Returns the present and dismiss methods in an array */ +export function useIonPopover>( + component: React.ComponentClass | React.FC, + componentProps?: T +): UseIonPopoverResult; +export function useIonPopover(component: JSX.Element, componentProps?: any): UseIonPopoverResult; export function useIonPopover(component: ReactComponentOrElement, componentProps?: any): UseIonPopoverResult { const controller = useOverlay( 'IonPopover',