-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
render
to NavigationItem (#3709)
Co-authored-by: mark-tate <[email protected]>
- Loading branch information
1 parent
83a2a7f
commit 34e8c9c
Showing
15 changed files
with
480 additions
and
88 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@salt-ds/core": minor | ||
--- | ||
|
||
Added `render` prop to `NavigationItem`. The `render` prop enables the substitution of the default anchor tag with an alternate link, such as React Router, facilitating integration with routing libraries. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
packages/core/src/__tests__/__e2e__/utils/renderProps.cy.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { renderProps } from "@salt-ds/core"; | ||
import { mount } from "cypress/react18"; | ||
import type { ComponentPropsWithoutRef } from "react"; | ||
|
||
describe("renderProps function", () => { | ||
const Button = (props: ComponentPropsWithoutRef<"button">) => ( | ||
<button {...props} /> | ||
); | ||
|
||
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", | ||
}; | ||
|
||
mount(renderProps(Button, props)); | ||
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", () => { | ||
const renderFunction = (props: { className: string }) => ( | ||
<Button className={props.className}>Button Children</Button> | ||
); | ||
const props = { | ||
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", | ||
"test-class", | ||
); | ||
}); | ||
|
||
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", | ||
}; | ||
|
||
mount(renderProps("button", props)); | ||
cy.findByRole("button", { name: "Button Children" }).should("exist"); | ||
cy.findByRole("button", { name: "Button Children" }).should( | ||
"have.class", | ||
"test-class", | ||
); | ||
}); | ||
}); |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import type { ComponentPropsWithoutRef } from "react"; | ||
import { renderProps } from "../utils"; | ||
|
||
interface NavigationItemActionProps extends ComponentPropsWithoutRef<any> {} | ||
|
||
export function NavigationItemAction(props: NavigationItemActionProps) { | ||
return renderProps("a", props); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { | ||
type ElementType, | ||
type ReactElement, | ||
cloneElement, | ||
isValidElement, | ||
} from "react"; | ||
import { mergeProps } from "./mergeProps"; | ||
|
||
export interface RenderPropsType { | ||
render?: ReactElement | ((props: any) => ReactElement); | ||
} | ||
|
||
export function renderProps<Type extends ElementType>( | ||
Type: Type, | ||
props: RenderPropsType & React.ComponentProps<Type>, | ||
): ReactElement { | ||
const { render, ...rest } = props; | ||
// Case 1: If render is a valid React element, clone it with merged props | ||
if (isValidElement(render)) { | ||
const renderProps = render.props as React.ComponentProps<Type>; | ||
return cloneElement(render, mergeProps(rest, renderProps)); | ||
} | ||
|
||
const restProps = rest as React.ComponentProps<Type>; | ||
|
||
// Case 2: If render is a function, call it with the rest of the props | ||
if (typeof render === "function") { | ||
const renderedElement = render(restProps); | ||
if (isValidElement(renderedElement)) { | ||
return renderedElement; | ||
} | ||
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} />; | ||
} |
Oops, something went wrong.