diff --git a/packages/elements-react/src/components/card/card-two-step.tsx b/packages/elements-react/src/components/card/card-two-step.tsx index 9dba5661f..434453f91 100644 --- a/packages/elements-react/src/components/card/card-two-step.tsx +++ b/packages/elements-react/src/components/card/card-two-step.tsx @@ -8,6 +8,7 @@ import { UiNodeInputAttributes, } from "@ory/client-fetch" import { useState } from "react" +import { useFormContext } from "react-hook-form" import { OryCard, OryCardContent, OryCardFooter } from "." import { useComponents, useNodeSorter, useOryFlow } from "../../context" import { useNodesGroups } from "../../util/ui" @@ -15,12 +16,13 @@ import { OryForm } from "../form/form" import { OryCardValidationMessages } from "../form/messages" import { Node } from "../form/nodes/node" import { OryFormSocialButtonsForm } from "../form/social" -import { OryCardHeader } from "./header" import { filterZeroStepGroups, getFinalNodes, isChoosingMethod, } from "./card-two-step.utils" +import { OryCardHeader } from "./header" +import { isGroupImmediateSubmit } from "../../theme/default/utils/form" enum ProcessStep { ProvideIdentifier, @@ -39,7 +41,7 @@ export function OryTwoStepCard() { const [selectedGroup, setSelectedGroup] = useState< UiNodeGroupEnum | undefined >() - const { Form, Card } = useComponents() + const { Form } = useComponents() const { flowType } = useOryFlow() const nodeSorter = useNodeSorter() @@ -80,7 +82,13 @@ export function OryTwoStepCard() { {step === ProcessStep.ProvideIdentifier && hasOidc && ( )} - + + isGroupImmediateSubmit(method + "") + ? setSelectedGroup(method as UiNodeGroupEnum) + : undefined + } + > {step === ProcessStep.ProvideIdentifier && zeroStepGroups @@ -91,13 +99,10 @@ export function OryTwoStepCard() { {flowType === FlowType.Login && ( )} - {options.map((option) => ( - setSelectedGroup(option)} - /> - ))} + )} {step === ProcessStep.ExecuteAuthMethod && ( @@ -116,6 +121,33 @@ export function OryTwoStepCard() { ) } +type AuthMethodListProps = { + options: UiNodeGroupEnum[] + setSelectedGroup: (group: UiNodeGroupEnum) => void +} + +function AuthMethodList({ options, setSelectedGroup }: AuthMethodListProps) { + const { Card } = useComponents() + const { setValue } = useFormContext() + + const handleClick = (group: UiNodeGroupEnum) => { + if (isGroupImmediateSubmit(group)) { + // If the method is "immediate submit" (e.g. the method's submit button should be triggered immediately) + // then the methid needs to be added to the form data. + setValue("method", group) + } else { + setSelectedGroup(group) + } + } + return options.map((option) => ( + handleClick(option)} + /> + )) +} + type BackButtonProps = { onClick?: () => void href?: string diff --git a/packages/elements-react/src/components/form/form.tsx b/packages/elements-react/src/components/form/form.tsx index 2400f8f27..2ff964b1d 100644 --- a/packages/elements-react/src/components/form/form.tsx +++ b/packages/elements-react/src/components/form/form.tsx @@ -182,9 +182,11 @@ type DeepPartialTwoLevels = { export type OryFlowComponentOverrides = DeepPartialTwoLevels -export type OryFormProps = PropsWithChildren +export type OryFormProps = PropsWithChildren<{ + onAfterSubmit?: (method: string | number | boolean | undefined) => void +}> -export function OryForm({ children }: OryFormProps) { +export function OryForm({ children, onAfterSubmit }: OryFormProps) { const { Form } = useComponents() const flowContainer = useOryFlow() const methods = useForm({ @@ -272,6 +274,7 @@ export function OryForm({ children }: OryFormProps) { }) break } + onAfterSubmit?.(data.method) } const hasMethods = diff --git a/packages/elements-react/src/theme/default/components/card/auth-methods.tsx b/packages/elements-react/src/theme/default/components/card/auth-methods.tsx index 8fd938262..5ccb3493d 100644 --- a/packages/elements-react/src/theme/default/components/card/auth-methods.tsx +++ b/packages/elements-react/src/theme/default/components/card/auth-methods.tsx @@ -3,11 +3,11 @@ import { useIntl } from "react-intl" import { OryCardAuthMethodListItemProps } from "@ory/elements-react" - import code from "../../assets/icons/code.svg" import passkey from "../../assets/icons/passkey.svg" import password from "../../assets/icons/password.svg" import webauthn from "../../assets/icons/webauthn.svg" +import { isGroupImmediateSubmit } from "../../utils/form" const iconsMap: Record = { code, @@ -27,8 +27,9 @@ export function DefaultAuthMethodListItem({ return (