File tree 5 files changed +114
-0
lines changed
__docs__/wonder-blocks-core
packages/wonder-blocks-core/src
5 files changed +114
-0
lines changed Original file line number Diff line number Diff line change
1
+ ---
2
+ " @khanacademy/wonder-blocks-core " : minor
3
+ ---
4
+
5
+ - Add the ` Id ` component for cases where ` useId ` cannot be used directly
Original file line number Diff line number Diff line change
1
+ import * as React from "react" ;
2
+
3
+ import { Meta } from "@storybook/react" ;
4
+ import { View , Id } from "@khanacademy/wonder-blocks-core" ;
5
+ import { Body , BodyMonospace } from "@khanacademy/wonder-blocks-typography" ;
6
+ import { Strut } from "@khanacademy/wonder-blocks-layout" ;
7
+ import { spacing } from "@khanacademy/wonder-blocks-tokens" ;
8
+
9
+ export default {
10
+ title : "Packages / Core / Id" ,
11
+
12
+ parameters : {
13
+ chromatic : {
14
+ // We don't need a snapshot for this.
15
+ disableSnapshot : true ,
16
+ } ,
17
+ } ,
18
+ } as Meta ;
19
+
20
+ export const GeneratedIdExample = ( ) => (
21
+ < View >
22
+ < Id >
23
+ { ( id ) => (
24
+ < View style = { { flexDirection : "row" } } >
25
+ < Body > Generated identifier: </ Body >
26
+ < Strut size = { spacing . xSmall_8 } />
27
+ < BodyMonospace > { id } </ BodyMonospace >
28
+ </ View >
29
+ ) }
30
+ </ Id >
31
+ </ View >
32
+ ) ;
33
+
34
+ export const PassedThroughIdExample = ( ) => (
35
+ < View >
36
+ < Id id = "my-identifier" >
37
+ { ( id ) => (
38
+ < View style = { { flexDirection : "row" } } >
39
+ < Body > Passed through identifier: </ Body >
40
+ < Strut size = { spacing . xSmall_8 } />
41
+ < BodyMonospace > { id } </ BodyMonospace >
42
+ </ View >
43
+ ) }
44
+ </ Id >
45
+ </ View >
46
+ ) ;
Original file line number Diff line number Diff line change
1
+ import * as React from "react" ;
2
+
3
+ import { render } from "@testing-library/react" ;
4
+ import { Id } from "../id" ;
5
+
6
+ describe ( "Id" , ( ) => {
7
+ it ( "should provide an id to the children" , ( ) => {
8
+ // Arrange
9
+ const childrenFn = jest . fn ( ) . mockReturnValue ( null ) ;
10
+
11
+ // Act
12
+ render ( < Id > { childrenFn } </ Id > ) ;
13
+
14
+ // Assert
15
+ expect ( childrenFn ) . toHaveBeenCalledWith ( expect . any ( String ) ) ;
16
+ } ) ;
17
+
18
+ it ( "should pass through the given id to the children" , ( ) => {
19
+ // Arrange
20
+ const childrenFn = jest . fn ( ) . mockReturnValue ( null ) ;
21
+
22
+ // Act
23
+ render ( < Id id = "my-id" > { childrenFn } </ Id > ) ;
24
+
25
+ // Assert
26
+ expect ( childrenFn ) . toHaveBeenCalledWith ( "my-id" ) ;
27
+ } ) ;
28
+ } ) ;
Original file line number Diff line number Diff line change
1
+ import { useId } from "react" ;
2
+ import * as React from "react" ;
3
+
4
+ type Props = {
5
+ /**
6
+ * An identifier to use.
7
+ *
8
+ * If this is omitted, an identifier is generated.
9
+ */
10
+ id ?: string | undefined ;
11
+
12
+ /**
13
+ * A function that to render children with the given identifier.
14
+ */
15
+ children : ( id : string ) => React . ReactNode ;
16
+ } ;
17
+
18
+ /**
19
+ * A component that provides an identifier to its children.
20
+ *
21
+ * If an `id` prop is provided, that is passed through to the children;
22
+ * otherwise, a unique identifier is generated.
23
+ */
24
+ export const Id = ( { id, children} : Props ) => {
25
+ const generatedId = useId ( ) ;
26
+
27
+ // If we already have an ID, then use that.
28
+ // Otherwise, use the generated ID.
29
+ // NOTE: We can't call hooks conditionally, but it should be pretty cheap
30
+ // to call useId() and not use the result, rather than the alternative
31
+ // which would be to have a separate component for cases where we need
32
+ // to call the hook and then render the component conditionally.
33
+ return < > { children ( id ?? generatedId ) } </ > ;
34
+ } ;
Original file line number Diff line number Diff line change @@ -13,6 +13,7 @@ export {default as IDProvider} from "./components/id-provider";
13
13
export { default as UniqueIDProvider } from "./components/unique-id-provider" ;
14
14
export { default as addStyle } from "./util/add-style" ;
15
15
export { default as Server } from "./util/server" ;
16
+ export { Id } from "./components/id" ;
16
17
export {
17
18
useUniqueIdWithMock ,
18
19
useUniqueIdWithoutMock ,
You can’t perform that action at this time.
0 commit comments