From 62179a2d639c042cbaa1dd2a79645fbafde41417 Mon Sep 17 00:00:00 2001 From: Jeff Yates Date: Wed, 11 Dec 2024 14:46:40 -0600 Subject: [PATCH] [wb1812.2.idcomponent] Add passthrough version to simplify IDProvider replacement --- __docs__/wonder-blocks-core/id.stories.tsx | 16 ++++++++++- .../src/components/__tests__/id.test.tsx | 11 ++++++++ .../wonder-blocks-core/src/components/id.tsx | 27 ++++++++++++++----- 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/__docs__/wonder-blocks-core/id.stories.tsx b/__docs__/wonder-blocks-core/id.stories.tsx index 504afd931..d6451692e 100644 --- a/__docs__/wonder-blocks-core/id.stories.tsx +++ b/__docs__/wonder-blocks-core/id.stories.tsx @@ -17,7 +17,7 @@ export default { }, } as Meta; -export const BasicExample = () => ( +export const GeneratedIdExample = () => ( {(id) => ( @@ -30,3 +30,17 @@ export const BasicExample = () => ( ); + +export const PassedThroughIdExample = () => ( + + + {(id) => ( + + Passed through identifier: + + {id} + + )} + + +); diff --git a/packages/wonder-blocks-core/src/components/__tests__/id.test.tsx b/packages/wonder-blocks-core/src/components/__tests__/id.test.tsx index 7b0869aef..6c2abbdf0 100644 --- a/packages/wonder-blocks-core/src/components/__tests__/id.test.tsx +++ b/packages/wonder-blocks-core/src/components/__tests__/id.test.tsx @@ -14,4 +14,15 @@ describe("Id", () => { // Assert expect(childrenFn).toHaveBeenCalledWith(expect.any(String)); }); + + it("should pass through the given id to the children", () => { + // Arrange + const childrenFn = jest.fn().mockReturnValue(null); + + // Act + render({childrenFn}); + + // Assert + expect(childrenFn).toHaveBeenCalledWith("my-id"); + }); }); diff --git a/packages/wonder-blocks-core/src/components/id.tsx b/packages/wonder-blocks-core/src/components/id.tsx index 8a0b0b084..7bf054302 100644 --- a/packages/wonder-blocks-core/src/components/id.tsx +++ b/packages/wonder-blocks-core/src/components/id.tsx @@ -2,6 +2,13 @@ import {useId} from "react"; import * as React from "react"; type Props = { + /** + * An identifier to use. + * + * If this is omitted, an identifier is generated. + */ + id?: string | undefined; + /** * A function that to render children with the given identifier. */ @@ -9,13 +16,19 @@ type Props = { }; /** - * A component that provides a unique identifier to its children. + * A component that provides an identifier to its children. * - * This component is useful when you need to generate unique identifiers for - * elements in components that cannot use hooks. Where possible, use `useId` - * instead. + * If an `id` prop is provided, that is passed through to the children; + * otherwise, a unique identifier is generated. */ -export const Id = ({children}: Props) => { - const id = useId(); - return <>{children(id)}; +export const Id = ({id, children}: Props) => { + const generatedId = useId(); + + // If we already have an ID, then use that. + // Otherwise, use the generated ID. + // NOTE: We can't call hooks conditionally, but it should be pretty cheap + // to call useId() and not use the result, rather than the alternative + // which would be to have a separate component for cases where we need + // to call the hook and then render the component conditionally. + return <>{children(id ?? generatedId)}; };