Skip to content

Commit

Permalink
[wb1812.2.idcomponent] Add passthrough version to simplify IDProvider…
Browse files Browse the repository at this point in the history
… replacement
  • Loading branch information
somewhatabstract committed Dec 16, 2024
1 parent 479c663 commit e8b1a5e
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 8 deletions.
16 changes: 15 additions & 1 deletion __docs__/wonder-blocks-core/id.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default {
},
} as Meta;

export const BasicExample = () => (
export const GeneratedIdExample = () => (
<View>
<Id>
{(id) => (
Expand All @@ -30,3 +30,17 @@ export const BasicExample = () => (
</Id>
</View>
);

export const PassedThroughIdExample = () => (
<View>
<Id id="my-identifier">
{(id) => (
<View style={{flexDirection: "row"}}>
<Body>Passed through identifier: </Body>
<Strut size={spacing.xSmall_8} />
<BodyMonospace>{id}</BodyMonospace>
</View>
)}
</Id>
</View>
);
11 changes: 11 additions & 0 deletions packages/wonder-blocks-core/src/components/__tests__/id.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(<Id id="my-id">{childrenFn}</Id>);

// Assert
expect(childrenFn).toHaveBeenCalledWith("my-id");
});
});
27 changes: 20 additions & 7 deletions packages/wonder-blocks-core/src/components/id.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,33 @@ 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.
*/
children: (id: string) => React.ReactNode;
};

/**
* 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)}</>;
};

0 comments on commit e8b1a5e

Please sign in to comment.