Skip to content

Commit

Permalink
fix: implement component merging instead of usign lodash
Browse files Browse the repository at this point in the history
  • Loading branch information
jonas-jonas committed Nov 5, 2024
1 parent 6cb5150 commit ed1439f
Show file tree
Hide file tree
Showing 12 changed files with 168 additions and 105 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

71 changes: 47 additions & 24 deletions packages/elements-react/api-report/elements-react-theme.api.json
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,53 @@
"endIndex": 8
}
},
{
"kind": "Function",
"canonicalReference": "@ory/elements-react!getOryComponents:function(1)",
"docComment": "",
"excerptTokens": [
{
"kind": "Content",
"text": "declare function getOryComponents(overrides?: "
},
{
"kind": "Reference",
"text": "OryFlowComponentOverrides",
"canonicalReference": "@ory/elements-react!~OryFlowComponentOverrides:type"
},
{
"kind": "Content",
"text": "): "
},
{
"kind": "Reference",
"text": "OryFlowComponents",
"canonicalReference": "@ory/elements-react!~OryFlowComponents:type"
},
{
"kind": "Content",
"text": ";"
}
],
"fileUrlPath": "dist/theme/default/index.d.ts",
"returnTypeTokenRange": {
"startIndex": 3,
"endIndex": 4
},
"releaseTag": "Public",
"overloadIndex": 1,
"parameters": [
{
"parameterName": "overrides",
"parameterTypeTokenRange": {
"startIndex": 1,
"endIndex": 2
},
"isOptional": true
}
],
"name": "getOryComponents"
},
{
"kind": "Function",
"canonicalReference": "@ory/elements-react!Login:function(1)",
Expand Down Expand Up @@ -750,30 +797,6 @@
"endIndex": 8
}
},
{
"kind": "Variable",
"canonicalReference": "@ory/elements-react!OryDefaultComponents:var",
"docComment": "",
"excerptTokens": [
{
"kind": "Content",
"text": "OryDefaultComponents: "
},
{
"kind": "Reference",
"text": "OryFlowComponents",
"canonicalReference": "@ory/elements-react!~OryFlowComponents:type"
}
],
"fileUrlPath": "dist/theme/default/index.d.ts",
"isReadonly": true,
"releaseTag": "Public",
"name": "OryDefaultComponents",
"variableTypeTokenRange": {
"startIndex": 1,
"endIndex": 2
}
},
{
"kind": "Function",
"canonicalReference": "@ory/elements-react!Recovery:function(1)",
Expand Down
10 changes: 5 additions & 5 deletions packages/elements-react/api-report/elements-react-theme.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ export type ErrorFlowContextProps = {
config: OryClientConfiguration;
};

// Warning: (ae-forgotten-export) The symbol "OryFlowComponents" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
export function getOryComponents(overrides?: OryFlowComponentOverrides): OryFlowComponents;

// @public (undocumented)
export function Login({ flow, config, children, components: flowOverrideComponents, }: PropsWithChildren<LoginFlowContextProps>): react_jsx_runtime.JSX.Element;

Expand All @@ -81,11 +86,6 @@ export type LoginFlowContextProps = {
config: OryClientConfiguration;
};

// Warning: (ae-forgotten-export) The symbol "OryFlowComponents" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
export const OryDefaultComponents: OryFlowComponents;

// @public (undocumented)
export function Recovery({ flow, config, children, components: flowOverrideComponents, }: PropsWithChildren<RecoveryFlowContextProps>): react_jsx_runtime.JSX.Element;

Expand Down
1 change: 0 additions & 1 deletion packages/elements-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
"class-variance-authority": "0.7.0",
"clsx": "2.1.1",
"input-otp": "1.2.4",
"lodash.merge": "4.6.2",
"react-hook-form": "7.53.0",
"react-intl": "6.7.0",
"tailwind-merge": "2.5.2",
Expand Down
7 changes: 2 additions & 5 deletions packages/elements-react/src/tests/jest/test-utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
// SPDX-License-Identifier: Apache-2.0

import { render, RenderOptions } from "@testing-library/react"
import { merge } from "lodash"
import { ComponentProps, PropsWithChildren, ReactElement } from "react"
import { OryFlowComponentOverrides } from "../../components"
import { OryComponentProvider } from "../../context/component"
import { OryDefaultComponents } from "../../theme/default"
import { getOryComponents } from "../../theme/default"
import { OryClientConfiguration } from "../../util"
export const defaultConfiguration: OryClientConfiguration = {
name: "test",
Expand All @@ -30,9 +29,7 @@ const ComponentProvider = ({
children,
components,
}: PropsWithChildren<ComponetOverrider>) => (
<OryComponentProvider
components={merge({}, OryDefaultComponents, components)}
>
<OryComponentProvider components={getOryComponents(components)}>
{children}
</OryComponentProvider>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright © 2024 Ory Corp
// SPDX-License-Identifier: Apache-2.0

import { getOryComponents } from "./default-components"

const CustomComponent = jest.fn()

describe("DefaultComponent", () => {
test("can override card component", () => {
const result = getOryComponents({
Card: { AuthMethodListItem: CustomComponent },
})
expect(result.Card.AuthMethodListItem).toBe(CustomComponent)
expect(result.Card.Content).toBeDefined()
})
test("can override form component", () => {
const result = getOryComponents({
Form: { OidcSettings: CustomComponent },
})
expect(result.Form.OidcSettings).toBe(CustomComponent)
expect(result.Form.Root).toBeDefined()
})
test("can override message component", () => {
const result = getOryComponents({
Message: { Content: CustomComponent },
})
expect(result.Message.Content).toBe(CustomComponent)
expect(result.Message.Root).toBeDefined()
})
test("can override page component", () => {
const result = getOryComponents({
Page: { Header: CustomComponent },
})
expect(result.Page.Header).toBe(CustomComponent)
})
test("can override node component", () => {
const result = getOryComponents({
Node: { Button: CustomComponent },
})
expect(result.Node.Button).toBe(CustomComponent)
expect(result.Node.Input).toBeDefined()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ import {
} from "./form/social"
import { DefaultText } from "./form/text"
import { DefaultCurrentIdentifierButton } from "./card/current-identifier-button"
import { OryFlowComponents } from "@ory/elements-react"
import {
OryFlowComponentOverrides,
OryFlowComponents,
} from "@ory/elements-react"
import {
DefaultFormSection,
DefaultFormSectionContent,
Expand All @@ -42,47 +45,60 @@ import { DefaultSettingsWebauthn } from "./settings/settings-webauthn"
import { DefaultSettingsPasskey } from "./settings/settings-passkey"
import { DefaultPageHeader } from "./generic/page-header"

export const OryDefaultComponents: OryFlowComponents = {
Card: {
Root: DefaultCard,
Footer: DefaultCardFooter,
Header: DefaultCardHeader,
Content: DefaultCardContent,
Logo: DefaultCardLogo,
Divider: DefaultHorizontalDivider,
AuthMethodListItem: DefaultAuthMethodListItem,

SettingsSection: DefaultFormSection,
SettingsSectionContent: DefaultFormSectionContent,
SettingsSectionFooter: DefaultFormSectionFooter,
},
Node: {
Button: DefaultButton,
OidcButton: DefaultButtonSocial,
CurrentIdentifierButton: DefaultCurrentIdentifierButton,
Input: DefaultInput,
CodeInput: DefaultPinCodeInput,
Image: DefaultImage,
Label: DefaultLabel,
Checkbox: DefaultCheckbox,
Text: DefaultText,
Anchor: DefaultLinkButton,
},
Form: {
Root: DefaultFormContainer,
Group: DefaultGroupContainer,
OidcRoot: DefaultSocialButtonContainer,
RecoveryCodesSettings: DefaultSettingsRecoveryCodes,
TotpSettings: DefaultSettingsTotp,
OidcSettings: DefaultSettingsOidc,
WebauthnSettings: DefaultSettingsWebauthn,
PasskeySettings: DefaultSettingsPasskey,
},
Message: {
Root: DefaultMessageContainer,
Content: DefaultMessage,
},
Page: {
Header: DefaultPageHeader,
},
export function getOryComponents(
overrides?: OryFlowComponentOverrides,
): OryFlowComponents {
// Yes, this could probably be easier by using lodash or a custom merge function.
// But, this makes it very explicit what can be overridden, and does not introduce issues with merging nested fields.
return {
Card: {
Root: overrides?.Card?.Root ?? DefaultCard,
Footer: overrides?.Card?.Footer ?? DefaultCardFooter,
Header: overrides?.Card?.Header ?? DefaultCardHeader,
Content: overrides?.Card?.Content ?? DefaultCardContent,
Logo: overrides?.Card?.Logo ?? DefaultCardLogo,
Divider: overrides?.Card?.Divider ?? DefaultHorizontalDivider,
AuthMethodListItem:
overrides?.Card?.AuthMethodListItem ?? DefaultAuthMethodListItem,
SettingsSection: overrides?.Card?.SettingsSection ?? DefaultFormSection,
SettingsSectionContent:
overrides?.Card?.SettingsSectionContent ?? DefaultFormSectionContent,
SettingsSectionFooter:
overrides?.Card?.SettingsSectionFooter ?? DefaultFormSectionFooter,
},
Node: {
Button: overrides?.Node?.Button ?? DefaultButton,
OidcButton: overrides?.Node?.OidcButton ?? DefaultButtonSocial,
CurrentIdentifierButton:
overrides?.Node?.CurrentIdentifierButton ??
DefaultCurrentIdentifierButton,
Input: overrides?.Node?.Input ?? DefaultInput,
CodeInput: overrides?.Node?.CodeInput ?? DefaultPinCodeInput,
Image: overrides?.Node?.Image ?? DefaultImage,
Label: overrides?.Node?.Label ?? DefaultLabel,
Checkbox: overrides?.Node?.Checkbox ?? DefaultCheckbox,
Text: overrides?.Node?.Text ?? DefaultText,
Anchor: overrides?.Node?.Anchor ?? DefaultLinkButton,
},
Form: {
Root: overrides?.Form?.Root ?? DefaultFormContainer,
Group: overrides?.Form?.Group ?? DefaultGroupContainer,
OidcRoot: overrides?.Form?.OidcRoot ?? DefaultSocialButtonContainer,
RecoveryCodesSettings:
overrides?.Form?.RecoveryCodesSettings ?? DefaultSettingsRecoveryCodes,
TotpSettings: overrides?.Form?.TotpSettings ?? DefaultSettingsTotp,
OidcSettings: overrides?.Form?.OidcSettings ?? DefaultSettingsOidc,
WebauthnSettings:
overrides?.Form?.WebauthnSettings ?? DefaultSettingsWebauthn,
PasskeySettings:
overrides?.Form?.PasskeySettings ?? DefaultSettingsPasskey,
},
Message: {
Root: overrides?.Message?.Root ?? DefaultMessageContainer,
Content: overrides?.Message?.Content ?? DefaultMessage,
},
Page: {
Header: overrides?.Page?.Header ?? DefaultPageHeader,
},
}
}
7 changes: 2 additions & 5 deletions packages/elements-react/src/theme/default/flows/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ import {
OryProvider,
OryTwoStepCard,
} from "@ory/elements-react"
import merge from "lodash.merge"
import { PropsWithChildren } from "react"
import { OryDefaultComponents } from "../components"
import { getOryComponents } from "../components"

export type LoginFlowContextProps = {
flow: LoginFlow
Expand All @@ -25,9 +24,7 @@ export function Login({
children,
components: flowOverrideComponents,
}: PropsWithChildren<LoginFlowContextProps>) {
const components = flowOverrideComponents
? merge({}, OryDefaultComponents, flowOverrideComponents)
: OryDefaultComponents
const components = getOryComponents(flowOverrideComponents)
return (
<OryProvider
config={config}
Expand Down
7 changes: 2 additions & 5 deletions packages/elements-react/src/theme/default/flows/recovery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ import {
OryProvider,
OryTwoStepCard,
} from "@ory/elements-react"
import merge from "lodash.merge"
import { PropsWithChildren } from "react"
import { OryDefaultComponents } from "../components"
import { getOryComponents } from "../components"

export type RecoveryFlowContextProps = {
flow: RecoveryFlow
Expand All @@ -25,9 +24,7 @@ export function Recovery({
children,
components: flowOverrideComponents,
}: PropsWithChildren<RecoveryFlowContextProps>) {
const components = flowOverrideComponents
? merge({}, OryDefaultComponents, flowOverrideComponents)
: OryDefaultComponents
const components = getOryComponents(flowOverrideComponents)
return (
<OryProvider
config={config}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ import {
OryProvider,
OryTwoStepCard,
} from "@ory/elements-react"
import merge from "lodash.merge"
import { PropsWithChildren } from "react"
import { OryDefaultComponents } from "../components"
import { getOryComponents } from "../components"

type RegistrationFlowContextProps = {
flow: RegistrationFlow
Expand All @@ -25,9 +24,7 @@ export function Registration({
components: flowOverrideComponents,
config,
}: PropsWithChildren<RegistrationFlowContextProps>) {
const components = flowOverrideComponents
? merge({}, OryDefaultComponents, flowOverrideComponents)
: OryDefaultComponents
const components = getOryComponents(flowOverrideComponents)
return (
<OryProvider
config={config}
Expand Down
Loading

0 comments on commit ed1439f

Please sign in to comment.