Skip to content

Commit

Permalink
Allow null to be passed to renderProps to explictly skip using Type (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
joshwooding authored Jul 22, 2024
1 parent 0008528 commit 43d9b5a
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 19 deletions.
80 changes: 64 additions & 16 deletions packages/core/src/__tests__/__e2e__/utils/renderProps.cy.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { renderProps } from "@salt-ds/core";
import { mount } from "cypress/react18";
import type { ComponentPropsWithoutRef } from "react";

describe("renderProps function", () => {
Expand All @@ -8,12 +7,13 @@ describe("renderProps function", () => {
);

it("should merge the props and render the JSX element when `render` is a valid React element", () => {
const props = {
render: <Button>Button Children</Button>,
className: "test-class",
};
cy.mount(
renderProps(Button, {
render: <Button>Button Children</Button>,
className: "test-class",
}),
);

mount(renderProps(Button, props));
cy.findByRole("button", { name: "Button Children" }).should("exist");
cy.findByRole("button", { name: "Button Children" }).should(
"have.class",
Expand All @@ -25,12 +25,14 @@ describe("renderProps function", () => {
const renderFunction = (props: { className: string }) => (
<Button className={props.className}>Button Children</Button>
);
const props = {
render: renderFunction,
className: "test-class",
};

mount(renderProps(Button, props));
cy.mount(
renderProps(Button, {
render: renderFunction,
className: "test-class",
}),
);

cy.findByRole("button", { name: "Button Children" }).should("exist");
cy.findByRole("button", { name: "Button Children" }).should(
"have.class",
Expand All @@ -39,12 +41,58 @@ describe("renderProps function", () => {
});

it("should render the Type component with the rest of the props when `render` is not provided", () => {
const props = {
className: "test-class",
children: "Button Children",
};
cy.mount(
renderProps("button", {
className: "test-class",
children: "Button Children",
}),
);

cy.findByRole("button", { name: "Button Children" }).should("exist");
cy.findByRole("button", { name: "Button Children" }).should(
"have.class",
"test-class",
);
});

it("should throw if render and type are not provided", () => {
expect(() =>
cy.mount(
renderProps(null, {
className: "test-class",
children: "Button Children",
}),
),
).to.throw("Type or render should be provided");
});

it("should render the JSX element when `render` is a valid React element and default type is null", () => {
cy.mount(
renderProps(null, {
render: <Button>Button Children</Button>,
className: "test-class",
}),
);

cy.findByRole("button", { name: "Button Children" }).should("exist");
cy.findByRole("button", { name: "Button Children" }).should(
"have.class",
"test-class",
);
});

it("should call the function with the rest of the props and render the returned element when `render` is a function and default type is null", () => {
const renderFunction = (props: { className: string }) => (
<Button className={props.className}>Button Children</Button>
);

cy.mount(
renderProps(null, {
render: renderFunction,
className: "test-class",
}),
);

mount(renderProps("button", props));
cy.findByRole("button", { name: "Button Children" }).should("exist");
cy.findByRole("button", { name: "Button Children" }).should(
"have.class",
Expand Down
10 changes: 7 additions & 3 deletions packages/core/src/utils/renderProps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface RenderPropsType {
}

export function renderProps<Type extends ElementType>(
Type: Type,
Type: Type | null,
props: RenderPropsType & ComponentProps<Type>,
): ReactElement {
const { render, ...rest } = props;
Expand All @@ -33,6 +33,10 @@ export function renderProps<Type extends ElementType>(
throw new Error("Render function did not return a valid React element");
}

// Case 3: If render is not provided, render the Type component with the rest of the props
return <Type {...restProps} />;
if (Type) {
// Case 3: If render is not provided, render the Type component with the rest of the props
return <Type {...restProps} />;
}

throw new Error("Type or render should be provided");
}

0 comments on commit 43d9b5a

Please sign in to comment.